Suppression de données utiliser par une boucle, dans une boucle [Résolu]

Signaler
Messages postés
39
Date d'inscription
dimanche 22 février 2009
Statut
Membre
Dernière intervention
29 mars 2010
-
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
-
Bon, en gros:
pour chaque élément d'un liste, si l'élément prend une certaine valeur, je le supprime.

il semblerait que ce ne soit pas prévu et autoriser par Maitre C#. En soit, ça ce tiens, mais il n'y aurait pas un truc du genre: "removeLater()'?

Merci et bien le bonjour chez vous.

Tagadatsointsoin!!!

10 réponses

Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
49
Avec les méthodes remove et removeAt des listes, non?
Merci de préciser la question voire éven. d'ajouter du code.

<hr />
-Blog-
-Site Perso-
Messages postés
276
Date d'inscription
lundi 8 septembre 2008
Statut
Membre
Dernière intervention
15 avril 2013
2
Bonjour,

En effet, il n'est pas possible de supprimer ou d'ajouter un élément à une collection pendant qu'on est en train d'itérer dessus.

Une solution pourrait d'être de renseigner une List des index des éléments à suprimer puis d'itérer sur cette liste et d'utiliser RemoveAt  sur ta List<string>

ed73
Messages postés
1160
Date d'inscription
vendredi 23 juillet 2004
Statut
Membre
Dernière intervention
21 octobre 2010
17
Le plus simple et efficace est simplement de boucler avec un for inversé. Le foreach enmpeche la suppression. Le for n'empeche pas la suppression mais engendre des bugs (evidemment, on loupe des valeurs)

for (int i = myList.Count - 1; i >= 0; --i)
{
myList.RemoveAt(i);
}
Messages postés
39
Date d'inscription
dimanche 22 février 2009
Statut
Membre
Dernière intervention
29 mars 2010

Voila le code:
                List<string> toto = new List<string>();
                toto.Add("a");
                toto.Add("c");
                toto.Add("d");
                foreach (string lettre in toto)
                {
                    if (lettre == "c")
                    {
                        toto.Remove(lettre);
                    }
                }
Désole, je ne trouve pas comment le mettre avec des belle couleur.

voila l'erreur:
Collection was modified; enumeration operation may not execute.

a+

Tagadatsointsoin!!!
Messages postés
39
Date d'inscription
dimanche 22 février 2009
Statut
Membre
Dernière intervention
29 mars 2010

Merci bien, finalement, je vais adopté une tournure d'esprit plus positive: créer une liste des éléments que je veux garder...
a+

Tagadatsointsoin!!!
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
49
ed73> Bien sûr que c'est faisable, et encore heureux!
Ce qui n'est pas possible, c'est de le faire lorsqu'on travaille avec un Enumerator...

La boucle for convient tout à fait, avec les méthodes remove ou removeAt comment indiqué dans le premier poste et dans celui de leprov...

<hr />
-Blog-
-Site Perso-
Messages postés
276
Date d'inscription
lundi 8 septembre 2008
Statut
Membre
Dernière intervention
15 avril 2013
2
Je me suis exprimé un peu vite, il est bien évident que je voulais parler de foreach.

Par contre il y a des cas (rares) où l'utilisation de for() n'est pas possible. Actuellement je travaille avec Microsoft.Office.Interop.MSProject
(automation Microsoft Project) et il faut impérativment parcourir les diverses collections avec un énumérateur car il y a souvent des éléments null dans les collections qui ne sont pas comptabilisés par le Count et ce de manière totalement aléatoire, le seul moyen de ne rien rater est d'utiliser foreach(), mais bon c'est peut-être un bug de Project.

ed73
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
49
Ha?
Tu as un exemple concret? jamais entendu parlé de ça...

<hr />
-Blog-
-Site Perso-
Messages postés
276
Date d'inscription
lundi 8 septembre 2008
Statut
Membre
Dernière intervention
15 avril 2013
2
Voici comment je m'en suis aperçu.

Pour itérer sur les ressources affectées à une tâche on avait une boucle

for(int i = 1;i<=Task.Resources.Count;i++)
   if(Task.Resources[i]!=null)
      DoSomething(Task.Resources[i]));

Il manquait systématiquement plusieures ressources, après plusieurs essais j'ai finalement fait un truc stupide pour voir

for(int i = 1;i<=Task.Resources.Count + 10;i++)
   if(Task.Resources[i]!=null)
  
    DoSomething(Task.Resources[i]));

Eh bien ça a marché jusqu'à Task.Resources.Count + 3 et j'ai récupéré toutes les ressources.

Finalement la solution était

foreach(Resource res in Task.Resources)
   DoSomething(res);

L'itération se fait correctement et je récupère toutes les ressources. Je pense que MSProject ne gère pas les collections comme il faudrait et ne comptabilise pas les éléments null dans le Count.
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
49
Etrange cette histoire là...
Quoi qu'il en soit, ce n'est pas un problème de boucle comme j'ai crû comprendre, mais plutôt d'une property qui retourne pas correctement le nombre d'élément, ce qui est quand même bien différent...

Je ne peux pas faire de testes supplémentaires, je n'ai pas les outils nécessaire pour ça installé.

<hr />
-Blog-
-Site Perso-