web-dev-qa-db-fra.com

Supprimer des éléments d'une liste dans une autre

J'essaie de comprendre comment parcourir une liste générique d'éléments que je souhaite supprimer d'une autre liste.

Alors disons que j'ai ceci comme exemple hypothétique

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();

Je veux parcourir list1 avec un foreach et supprimer chaque élément de List1 qui est également contenu dans List2.

Je ne sais pas trop comment y parvenir, car foreach n'est pas basé sur un index.

171
PositiveGuy

Vous pouvez utiliser sauf :

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
List<car> result = list2.Except(list1).ToList();

Vous n'avez probablement même pas besoin de ces variables temporaires:

List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();

Notez que Except ne modifie aucune liste - il crée une nouvelle liste avec le résultat.

316
Mark Byers

Vous n'avez pas besoin d'index, car la classe List<T> vous permet de supprimer des éléments par valeur plutôt que d'index à l'aide de la fonction Remove.

foreach(car item in list1) list2.Remove(item);
31
Adam Robinson

Je recommanderais d'utiliser le méthodes d'extension LINQ . Vous pouvez facilement le faire avec une ligne de code comme ceci:

list2 = list2.Except(list1).ToList();

Ceci suppose bien sûr que les objets de list1 que vous supprimez de list2 sont la même instance.

22
Berkshire

Dans mon cas, j'avais deux listes différentes, avec un identifiant commun, un peu comme une clé étrangère. La deuxième solution citée par "nzrytmn":

var result =  list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();

C’était celui qui convenait le mieux à ma situation. Je devais charger une DropDownList sans les enregistrements déjà enregistrés.

Merci !!!

Ceci est mon code:

t1 = new T1();
t2 = new T2();

List<T1> list1 = t1.getList();
List<T2> list2 = t2.getList();

ddlT3.DataSource= list2.Where(s => !list1.Any(p => p.Id == s.ID)).ToList();
ddlT3.DataTextField = "AnyThing";
ddlT3.DataValueField = "IdAnyThing";
ddlT3.DataBind();
15

Vous pouvez utiliser LINQ, mais j'utiliserais la méthode RemoveAll. Je pense que c'est celui qui exprime le mieux votre intention.

var integers = new List<int> { 1, 2, 3, 4, 5 };

var remove = new List<int> { 1, 3, 5 };

integers.RemoveAll(i => remove.Contains(i));
13
João Angelo
list1.RemoveAll(l => list2.Contains(l));

Solution 1: Vous pouvez faire comme ça:

List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();

Mais dans certains cas, cette solution peut ne pas fonctionner. si ce n'est pas le travail, vous pouvez utiliser ma deuxième solution.

Solution 2:

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();

nous prétendons que list1 est votre liste principale et list2 est votre liste secondaire et que vous souhaitez obtenir des éléments de liste1 sans éléments de liste2.

 var result =  list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();
5
nzrytmn