386 votes

Comment sauter une itération d'une boucle `foreach` ?

En Perl, je peux sauter une itération de foreach (ou de n'importe quelle boucle) avec une balise next; commandement.

Existe-t-il un moyen de sauter une itération et de passer à la boucle suivante en C# ?

 foreach (int number in numbers)
 {
     if (number < 0)
     {
         // What goes here to skip over the loop?
     }

     // otherwise process number
 }

0 votes

Il est tout aussi important d'avertir l'utilisateur de sa mauvaise saisie que de l'ignorer !

804voto

John Feminella Points 116878

Vous voulez :

foreach (int number in numbers) //   <--- go back to here --------+
{                               //                                |
    if (number < 0)             //                                |
    {                           //                                |
        continue;   // Skip the remainder of this iteration. -----+
    }

    // do work
}

Voici plus d'informations sur le continue mot-clé .


Mise à jour : En réponse à la question de suivi de Brian dans les commentaires :

Pourriez-vous préciser ce que je devrais faire si j'avais des boucles for imbriquées et que je voulais sauter l'itération de l'une des boucles étendues ?

for (int[] numbers in numberarrays) {
  for (int number in numbers) { // What to do if I want to
                                // jump the (numbers/numberarrays)?
  }
}

A continue s'applique toujours à l'étendue la plus proche, de sorte que vous ne pouvez pas l'utiliser pour sortir de la boucle la plus extérieure. Si une telle condition se produit, vous devrez faire quelque chose de plus compliqué en fonction de ce que vous voulez exactement, comme break de la boucle interne, alors continue sur la boucle extérieure. Voir ici pour la documentation sur le break mot-clé . Le site break Le mot clé C# est similaire au mot clé Perl last mot-clé.

En outre, envisagez de suivre la suggestion de Dustin de simplement filtrer les valeurs que vous ne souhaitez pas traiter au préalable :

foreach (var basket in baskets.Where(b => b.IsOpen())) {
  foreach (var fruit in basket.Where(f => f.IsTasty())) {
    cuteAnimal.Eat(fruit); // Om nom nom. You don't need to break/continue
                           // since all the fruits that reach this point are
                           // in available baskets and tasty.
  }
}

1 votes

Pourriez-vous préciser ce que je devrais faire si j'avais des boucles for imbriquées et que je voulais sauter l'itération de l'une des boucles étendues ? ex : for (int[] nombres dans tableaux de nombres) { for (int nombre dans nombres) { //Que faire si je veux sauter le (nombres/tableaux de nombres) } }

1 votes

C# goto est en fait utile pour la situation dont parle @Brian. Ajoutez une étiquette telle que nextArray: en bas de la boucle externe, puis goto nextArray; quand vous voulez y accéder.

60voto

Dustin Campbell Points 6323

Une autre approche consiste à filtrer en utilisant LINQ avant l'exécution de la boucle :

foreach ( int number in numbers.Where(n => n >= 0) )
{
    // process number
}

3 votes

+1. Bien que ce ne soit pas une réponse directe à la question, en pratique, je préférerais probablement cette solution à celle que j'ai proposée. L'utilisation de LINQ semble être un bon cas d'utilisation général pour filtrer les valeurs de boucle que vous ne voulez pas traiter.

3 votes

Est-ce que c'est juste plus ordonné ou est-ce que ce sera plus rapide dans la mesure où il y a moins de foreach ? Je suppose que LINQ est grandement optimisé, mais la section LINQ devra effectuer un foreach à un moment donné, donc théoriquement, si le jeu de données est grand et que le sous-ensemble "filtré" résultant est presque aussi grand, alors cela sera plus lent car un foreach doit se produire deux fois ? Peut-être cela dépend-il du sous-ensemble de données résultant attendu ?

28voto

crashmstr Points 15302

Vous pouvez également inverser votre test if :

foreach ( int number in numbers )
{
     if ( number >= 0 )
     {
        //process number
     }
 }

0 votes

:) Merci ! Je suis arrivé à un exemple de base parce qu'il y avait certains critères au début de la boucle qui n'auraient pas besoin d'être traités, et d'autres qui étaient des erreurs qui devaient être attrapées.

4 votes

La réponse basée sur LINQ est agréable et élégante, mais l'utilisation d'une instruction if n'est pas mauvaise.

26voto

Tamas Czinege Points 49277
foreach ( int number in numbers )
{
    if ( number < 0 )
    {
        continue;
    }

    //otherwise process number
}

14voto

drewh Points 4457

Utilisez l'instruction continue :

foreach(object number in mycollection) {
     if( number < 0 ) {
         continue;
     }
  }

3 votes

Je ne comprends pas pourquoi il est upvoted, c'est faux puisqu'il boucle sur "o", pas sur "nombre".

0 votes

D'accord, peut-être est-ce un copier/coller des réponses précédentes ? Conceptuellement intéressant car c'est un foreach, mais assurez-vous que les variables sont cohérentes.

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