Supposons que j’aie l’extrait de code suivant:
var data=new List(){"One","Two","Three"}; for(int i=0 ; i<data.Count ; i++){ if(data[i]=="One"){ data.RemoveAt(i); } }
Le code suivant lève une exception.
Ma question est la suivante: quelle est la meilleure façon d’éviter cette exception et de supprimer l’élément en boucle?
Si vous devez supprimer des éléments, vous devez effectuer une itération en arrière afin de pouvoir supprimer des éléments de la fin de la liste:
var data=new List(){"One","Two","Three"}; for(int i=data.Count - 1; i > -1; i--) { if(data[i]=="One") { data.RemoveAt(i); } }
Cependant, il existe des moyens plus efficaces de le faire avec LINQ (comme indiqué par les autres réponses).
Vous pouvez utiliser List
pour gérer ceci:
data.RemoveAll(elem => elem == "One");
Je trouve une solution simple pour cela en utilisant foreach
et .ToArray()
var data=new List(){"One","Two","Three"}; foreach ( var d in data.ToArray()){ if(d =="One"){ data.Remove(d); } }
Vous pouvez essayer la méthode d’itération inversée de ChrisF pour supprimer votre élément.
Vous pourriez aussi simplement:
List.Remove("One");
Ou:
List.RemoveAll(i => i == "One"); // removes all instances
Et en finir avec ça. Il est inutile de parcourir la collection pour supprimer un seul élément.
Vous pouvez également utiliser une boucle en mouvement comme:
var data = new List() { "One", "Two", "Three", "One", "One", "Four" }; for (int i = 0; i < data.Count; i++) { if (data[i] == "One") { data.RemoveAt(i--); } }
Cette ligne de data.RemoveAt(i--);
stoppe l'effet de l'incrémentation dans la variable d'itération à la fin de la boucle, en cas de suppression de l'élément de la liste.
Il supprimera l'élément de l'index à la valeur d'itération actuelle, puis après avoir supprimé l'élément, l'iterator sera défini sur une valeur inférieure à celle qui est actuellement utilisée. À la fin de la boucle, l'incrément dans le corps de la boucle le déplacera vers le prochain index valide.
Voici un dotfiddle qui fonctionne
(Veuillez noter que, pour ma part, j'utilise la boucle inversée pour des situations comme celles-ci, car elles sont plus faciles à comprendre, cette réponse est juste pour afficher une autre manière d'y parvenir) .
Pourquoi ne décrivez-vous pas simplement la variable iterator?
var data=new List(){"One","Two","Three"}; for(int i=0 ; i
Voici un sale tour et je me demande quelle en sera la critique?
var data=new List(){"One","Two","Three"}; foreach (ssortingng itm in (data.ToArray())) { if ssortingng.Compare(name, "one", true) == 0) data.Remove(name); }
La solution générale ci-dessous crée une copie de la liste et gère l’index négatif:
foreach (void item_loopVariable in MyList.ToList) { item = item_loopVariable; }
var data = new List() { "One", "Two", "Three" }; data.RemoveAll(p=>p=="One");
var data=new List(){"One","Two","Three"}; for(int i=0; i
Vous pouvez utiliser la classe Stack
Stack myStack = new Stack (); foreach (var item in Enumerable.Range(1,1001)) myStack.Push("Str " + item.ToSsortingng()); while (myStack.Any()) Console.WriteLine("Now {0} items in Stack, removed item is {1}",myStack.Count,myStack.Pop()); Console.ReadKey();
J’ai dû supprimer plus d’un article de la liste. J’ai donc réinitialisé le nombre de listes. Y a-t-il une autre meilleure option?
for (int i = dtList.Count - 1; dtList.Count > 0; ) { DateTime tempDate = dtList[i].Item1.Date; var selectDates = dtList.FindAll(x => x.Item1.Date == tempDate.Date); selectDates.Sort((a, b) => a.Item1.CompareTo(b.Item1)); dtFilteredList.Add(Tuple.Create(selectDates[0].Item1, selectDates[0].Item2)); dtList.RemoveAll(x => x.Item1.Date == tempDate.Date); i = dtList.Count - 1; }
List list = new List (); list.Add("sasa"); list.Add("sames"); list.Add("samu"); list.Add("james"); for (int i = list.Count - 1; i >= 0; i--) { list.RemoveAt(i); }