una tiene tabla saber registros puede leer existe encontrar data como columna clave celda buscar c# linq list

c# - tiene - cómo verificar si el objeto ya existe en una lista



saber si existe una columna en datagridview c# (8)

Tengo una lista

List<MyObject> myList

y estoy agregando elementos a una lista y quiero verificar si ese objeto ya está en la lista.

entonces antes de hacer esto:

myList.Add(nextObject);

Quiero ver si nextObject ya está en la lista.

el objeto "MyObject" tiene varias propiedades, pero la comparación se basa en la coincidencia en dos propiedades.

¿Cuál es la mejor manera de hacer una verificación antes de agregar un nuevo "MyObject" a esta lista de "MyObject" s

la única solución que pensé fue cambiar de una lista a un diccionario y convertirla en una cadena concatenada de las propiedades (esto parece un poco poco elegante)

cualquier otra solución de limpieza usando list o LINQ u otra cosa?


¿Estás seguro de que necesitas una lista en este caso? Si está completando la lista con muchos elementos, el rendimiento se verá myList.Contains con myList.Contains o myList.Any ; el tiempo de ejecución será cuadrático. Es posible que desee considerar el uso de una mejor estructura de datos. Por ejemplo,

public class MyClass { public string Property1 { get; set; } public string Property2 { get; set; } } public class MyClassComparer : EqualityComparer<MyClass> { public override bool Equals(MyClass x, MyClass y) { if(x == null || y == null) return x == y; return x.Property1 == y.Property1 && x.Property2 == y.Property2; } public override int GetHashCode(MyClass obj) { return obj == null ? 0 : (obj.Property1.GetHashCode() ^ obj.Property2.GetHashCode()); } }

Puede usar un HashSet de la siguiente manera:

var set = new HashSet<MyClass>(new MyClassComparer()); foreach(var myClass in ...) set.Add(myClass);

Por supuesto, si esta definición de igualdad para MyClass es ''universal'', no necesita escribir una implementación de IEqualityComparer ; podría simplemente anular GetHashCode e Equals en la clase misma.


Aquí hay una aplicación de consola rápida para describir el concepto de cómo resolver su problema.

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication3 { public class myobj { private string a = string.Empty; private string b = string.Empty; public myobj(string a, string b) { this.a = a; this.b = b; } public string A { get { return a; } } public string B { get { return b; } } } class Program { static void Main(string[] args) { List<myobj> list = new List<myobj>(); myobj[] objects = { new myobj("a", "b"), new myobj("c", "d"), new myobj("a", "b") }; for (int i = 0; i < objects.Length; i++) { if (!list.Exists((delegate(myobj x) { return (string.Equals(x.A, objects[i].A) && string.Equals(x.B, objects[i].B)) ? true : false; }))) { list.Add(objects[i]); } } } } }

¡Disfrutar!


Depende de las necesidades de la situación específica. Por ejemplo, el enfoque del diccionario sería bastante bueno suponiendo:

  1. La lista es relativamente estable (no muchas inserciones / eliminaciones, para qué diccionarios no están optimizados)
  2. La lista es bastante grande (de lo contrario, la sobrecarga del diccionario no tiene sentido).

Si lo anterior no es cierto para su situación, solo use Any() :

Item wonderIfItsPresent = ... bool containsItem = myList.Any(item => item.UniqueProperty == wonderIfItsPresent.UniqueProperty);''

Esto enumerará a través de la lista hasta que encuentre una coincidencia, o hasta que llegue al final.


Editar: Primero dije:

Lo que no es elegante acerca de la solución del diccionario. Me parece perfectamente elegante, especialmente porque solo necesita establecer el comparador en la creación del diccionario.

Por supuesto, sin embargo, es poco elegante usar algo como clave cuando también es el valor.

Por lo tanto, usaría un HashSet. Si las operaciones posteriores requerían indexación, crearía una lista cuando finalizara la adición; de lo contrario, simplemente use el hashset.


Otro punto para mencionar es que debe asegurarse de que su función de igualdad sea la esperada. Debe anular el método equals para configurar qué propiedades de su objeto deben coincidir para que dos instancias se consideren iguales.

Entonces puedes hacer mylist.contains (item)


Si es sostenible usar esas 2 propiedades, podrías:

bool alreadyExists = myList.Any(x=> x.Foo=="ooo" && x.Bar == "bat");


Simple pero funciona

MyList.Remove(nextObject) MyList.Add(nextObject)

o

if (!MyList.Contains(nextObject)) MyList.Add(nextObject);


Simplemente use el método Contains . Tenga en cuenta que funciona basado en la función de igualdad Equals

bool alreadyExist = list.Contains(item);