comment vérifier si l’object existe déjà dans une liste

J’ai une liste

List myList 

et j’ajoute des éléments à une liste et je veux vérifier si cet object est déjà dans la liste.

alors avant de faire ceci:

  myList.Add(nextObject); 

Je veux voir si nextObject est déjà dans la liste.

l’object “MyObject” a un certain nombre de propriétés mais la comparaison est basée sur la correspondance sur deux propriétés.

Quelle est la meilleure façon d’effectuer une vérification avant d’append un nouveau “MyObject” à cette liste de “MyObject”?

la seule solution que je pensais était de passer d’une liste à un dictionnaire et de faire de la clé une chaîne concaténée des propriétés (cela semble peu élogieux)

d’autres solutions plus propres utilisant la liste ou LINQ ou quelque chose d’autre?

Cela dépend des besoins de la situation spécifique. Par exemple, l’approche par dictionnaire serait assez bonne en supposant:

  1. La liste est relativement stable (pas beaucoup d’insertions / suppressions, quels dictionnaires ne sont pas optimisés pour)
  2. La liste est assez volumineuse (sinon la surcharge du dictionnaire est inutile).

Si ce qui précède n’est pas vrai pour votre situation, utilisez Any() :

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

Cela énumérera à travers la liste jusqu’à ce qu’il trouve une correspondance, ou jusqu’à ce qu’il atteigne la fin.

Utilisez simplement la méthode Contains . Notez que cela fonctionne en fonction de la fonction d’égalité Equals

 bool alreadyExist = list.Contains(item); 

S’il est maintenable d’utiliser ces 2 propriétés, vous pouvez:

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

Êtes-vous sûr d’avoir besoin d’une liste dans ce cas? Si vous myList.Contains la liste avec de nombreux éléments, les performances en souffriront avec myList.Contains ou myList.Any ; le temps d’exécution sera quadratique. Vous pouvez envisager d’utiliser une meilleure structure de données. Par exemple,

  public class MyClass { public ssortingng Property1 { get; set; } public ssortingng Property2 { get; set; } } public class MyClassComparer : EqualityComparer { 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()); } } 

Vous pouvez utiliser un HashSet de la manière suivante:

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

Bien sûr, si cette définition d’égalité pour MyClass est «universelle», vous n’avez pas besoin d’écrire une implémentation IEqualityComparer ; vous pouvez simplement remplacer GetHashCode et Equals dans la classe elle-même.

Un autre point à mentionner est que vous devez vous assurer que votre fonction d’égalité est conforme à vos attentes. Vous devez remplacer la méthode égal pour définir quelles propriétés de votre object doivent correspondre pour que deux instances soient considérées comme égales.

Ensuite, vous pouvez simplement faire mylist.contains (item)

Voici une application de console rapide pour décrire le concept de la manière de résoudre votre problème.

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication3 { public class myobj { private ssortingng a = ssortingng.Empty; private ssortingng b = ssortingng.Empty; public myobj(ssortingng a, ssortingng b) { this.a = a; this.b = b; } public ssortingng A { get { return a; } } public ssortingng B { get { return b; } } } class Program { static void Main(ssortingng[] args) { List list = new List(); 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(xA, objects[i].A) && string.Equals(xB, objects[i].B)) ? true : false; }))) { list.Add(objects[i]); } } } } } 

Prendre plaisir!

Edit: J’avais d’abord dit:


Ce qui est inélégant sur la solution du dictionnaire. Cela me semble parfaitement élégant, car il suffit de définir le comparateur lors de la création du dictionnaire.


Bien sûr, il est inutile d’utiliser quelque chose comme clé lorsque c’est aussi la valeur.

Par conséquent, j’utiliserais un HashSet. Si des opérations ultérieures nécessitaient une indexation, je créerais une liste à partir du moment où l’ajout a été effectué, sinon utilisez simplement le hashset.

Simple mais ça marche

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

ou

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