47 votes

.NET - Supprimer d'une liste <T> dans une boucle 'foreach'

J'ai le code que je veux ressembler à ceci:

 List<Type> Os;

...

foreach (Type o in Os)
    if (o.cond)
        return;  // Quitting early is important for my case!
    else
        Os.Remove(o);

... // Other code
 

Cela ne fonctionne pas, car vous ne pouvez pas supprimer de la liste lorsque vous vous trouvez dans une boucle foreach sur cette liste:

Existe-t-il un moyen commun de résoudre le problème?

Je peux changer de type si nécessaire.

Option 2:

 List<Type> Os;

...

while (Os.Count != 0)
     if (Os[0].cond)
         return;
     else
         Os.RemoveAt(0);

... // Other code
 

Moche, mais ça devrait marcher.

59voto

Jon B Points 26872

Vous pouvez parcourir la liste à l’arrière:

 for (int i = myList.Count - 1; i >= 0; i--)
{
    if (whatever) myList.RemoveAt(i);
}
 


En réponse à votre commentaire sur le fait de vouloir quitter lorsque vous trouvez un élément que vous ne supprimez PAS, la meilleure solution serait alors d'utiliser une boucle while.

55voto

User Points 13983

Vous ne devez jamais retirer quoi que ce soit d'une collection sur laquelle vous effectuez une itération dans une boucle foreach. C'est fondamentalement comme scier la branche sur laquelle vous êtes assis.

Utilisez votre alternative while. C'est le chemin à parcourir.

31voto

LukeH Points 110965

Avez-vous vraiment besoin de le faire dans une boucle foreach ?

Cela donnera les mêmes résultats que vos exemples, c'est-à-dire que vous supprimerez tous les éléments de la liste jusqu'au premier élément correspondant à la condition (ou supprimerez tous les éléments si aucun ne correspond à la condition).

 int index = Os.FindIndex(x => x.cond);

if (index > 0)
    Os.RemoveRange(0, index);
else if (index == -1)
    Os.Clear();
 

15voto

Milhous Points 6362

Je suis un programmeur Java, mais quelque chose comme ça marche:

 List<Type> Os;
List<Type> Temp;
...
foreach (Type o in Os)
    if (o.cond)
        Temp.add(o);
Os.removeAll(Temp);  
 

13voto

Anzurio Points 4816

Je viens d'avoir ce problème avec ma bibliothèque d'analyse. J'ai essayé ceci:

 for (int i = 0; i < list.Count; i++)
{                
   if (/*condition*/)
   {
       list.RemoveAt(i);
       i--;
   }
}
 

C'est assez simple mais je n'ai pas pensé à un point de rupture.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X