Come posso saltare un'iterazione di un ciclo `foreach`?


324

In Perl posso saltare un'iterazione foreach (o qualsiasi ciclo) con un next;comando.

C'è un modo per saltare un'iterazione e passare al ciclo successivo in C #?

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

     // otherwise process number
 }

Avvisare l'utente con un input errato è importante quanto ignorarlo!
utileBee

Risposte:


664

Tu vuoi:

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

    // do work
}

Ecco di più sulla continueparola chiave .


Aggiornamento: in risposta alla domanda di follow-up di Brian nei commenti:

Potresti chiarire ulteriormente cosa farei se avessi annidato per i loop e volessi saltare l'iterazione di uno di quelli estesi?

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

A continuesi applica sempre all'ambito di chiusura più vicino, quindi non è possibile utilizzarlo per uscire dal ciclo più esterno. Se si presenta una condizione del genere, avresti bisogno di fare qualcosa di più complicato a seconda esattamente di ciò che desideri, come breakdal circuito interno, quindi continuedal circuito esterno. Vedi qui per la documentazione sulla breakparola chiave . La breakparola chiave C # è simile alla lastparola chiave Perl .

Inoltre, considera di prendere il suggerimento di Dustin per filtrare semplicemente i valori che non vuoi elaborare in anticipo:

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.
  }
}

Potresti chiarire ulteriormente cosa farei se avessi annidato per i loop e volessi saltare l'iterazione di uno di quelli estesi? es: for (int [] numeri nei numeri) {for (numero int nei numeri) {// Cosa fare se si desidera saltare i (numeri / numeri)}}
Brian

C # gotoè effettivamente utile per la situazione che @Brian sta chiedendo. Aggiungi un'etichetta come nextArray:nella parte inferiore del loop esterno e quindi goto nextArray;quando vuoi saltarci sopra.
Jacob Krall,

55

Un altro approccio è filtrare usando LINQ prima che il ciclo venga eseguito:

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

2
+1. Sebbene non sia una risposta diretta alla domanda, in pratica probabilmente preferirei questa soluzione a quella che ho proposto. L'uso di LINQ sembra un buon caso d'uso generale per filtrare i valori di loop che non si desidera elaborare.
John Feminella,

3
È solo più ordinato o sarà effettivamente più veloce in quanto c'è meno da predicare? Immagino che LINQ sia notevolmente ottimizzato, ma la sezione LINQ dovrà prevedere ad un certo punto in modo così teorico se il set di dati è grande e il sottoinsieme risultante 'filtrato' è quasi altrettanto grande, quindi questo sarà più lento di quanto deve accadere un foreach due volte? Quindi forse dipende dal sottoinsieme di dati risultante previsto?
Coops

25

Puoi anche capovolgere il tuo if test:


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

:) Grazie! Faccio un esempio di base perché all'inizio del ciclo c'erano alcuni criteri che non avrebbero dovuto essere elaborati e altri che erano errori che dovevano essere colti.
Brian

4
L'unica risposta basata su LINQ è buona e ha un'eleganza, ma usare un'istruzione if non è sbagliato.
crashmstr,

21
foreach ( int number in numbers )
{
    if ( number < 0 )
    {
        continue;
    }

    //otherwise process number
}

16

Puoi usare la continuedichiarazione.

Per esempio:

foreach(int number in numbers)
{
    if(number < 0)
    {
        continue;
    }
}

16

Un altro approccio che utilizza linq è:

foreach ( int number in numbers.Skip(1))
{   
    // process number  
}

Se si desidera saltare il primo di una serie di elementi.

Oppure utilizzare .SkipWherese si desidera specificare una condizione per saltare.


Questo è il modo più semplice (anche se forse la logica interna è la stessa) di farlo - ora che hai Linq disponibile. Tuttavia, è necessario assicurarsi che .Skip venga chiamato una sola volta per motivi di prestazioni. (Sì, vedo ora che questa non è la risposta diretta alla domanda di OP, anche se una preziosa aggiunta a questo elenco di risposte). +1
B Charles H,

8

Usa l'istruzione continue:

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

3
Non capisco perché è stato votato, questo è sbagliato dato che passa sopra "o", non "numero"
Fortuna

D'accordo, forse questa è una copia / incolla dalle risposte precedenti? Concettualmente prezioso in quanto è una foreach, ma assicurati che le variabili siano coerenti.
Antonio Ciolino,

0

Il modo più semplice per farlo è come di seguito:

//Skip First Iteration

foreach ( int number in numbers.Skip(1))

//Skip any other like 5th iteration

foreach ( int number in numbers.Skip(5))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.