web-dev-qa-db-fra.com

Liste C # - Supprimer des éléments en boucle/itération

Supposons que j'ai l'extrait de code suivant:

var data=new List<string>(){"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: quel est le meilleur moyen d'éviter cette exception et de supprimer l'élément en boucle?

38

Si vous devez supprimer des éléments, vous devez effectuer une itération inverse pour pouvoir supprimer des éléments à la fin de la liste:

var data=new List<string>(){"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).

88
ChrisF

Vous pouvez utiliser List<T>.RemoveAll pour gérer ceci:

data.RemoveAll(elem => elem == "One");
41
Reed Copsey

Je trouve une solution simple pour cela en utilisant foreach et .ToArray()

  var data=new List<string>(){"One","Two","Three"};
   foreach ( var d in data.ToArray()){
      if(d =="One"){
        data.Remove(d);
      }
    }
10
Pushpendra

Vous pouvez essayer la méthode d'itération inverse de ChrisF pour supprimer votre élément.

Vous pouvez 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.

4
Justin Niessner

Pourquoi ne pas simplement décrémenter la variable itérateur?

var data=new List<string>(){"One","Two","Three"};
for(int i=0 ; i<data.Count ; i++){
  if(data[i]=="One"){
    data.RemoveAt(i);
    i--; // <<<<<<<<<<<
  }
}
2
Pewpew

Voici un sale tour et je me demande quelle en sera la critique?

var data=new List<string>(){"One","Two","Three"};
foreach (string itm in (data.ToArray()))
{
  if string.Compare(name, "one", true) == 0) data.Remove(name);
}
1
B H

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;

}
1
alwaysVBNET
        var data = new List<string>() { "One", "Two", "Three" };
        data.RemoveAll(p=>p=="One");
0
Nivid Dholakia
var data=new List<string>(){"One","Two","Three"};
for(int i=0; i<data.Count; ){
  if(data[i]=="One") data.RemoveAt(i);
  else ++i;
}
0
Tutankhamen

Vous pouvez utiliser la classe Stack 

        Stack<string> myStack = new Stack<string>();

        foreach (var item in Enumerable.Range(1,1001))
            myStack.Push("Str " + item.ToString());

        while (myStack.Any())
            Console.WriteLine("Now {0} items in Stack, removed item is {1}",myStack.Count,myStack.Pop());

        Console.ReadKey();
0
Biju kalanjoor

Je devais supprimer plus d'un article de la liste. alors, j'ai 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;
}
0
Madhu