Como pular uma iteração de um loop `foreach`?

324

No Perl, posso pular uma iteração foreach (ou qualquer loop) com um next;comando.

Existe uma maneira de pular uma iteração e pular para o próximo loop em c #?

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

     // otherwise process number
 }
Brian
fonte
Notificar o usuário com sua entrada incorreta é tão importante quanto ignorá-la!
usefulBee

Respostas:

664

Você quer:

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

    // do work
}

Aqui está mais sobre a continuepalavra - chave .


Atualização: em resposta à pergunta de acompanhamento de Brian nos comentários:

Você poderia esclarecer melhor o que eu faria se tivesse feito um aninhamento de loops e quisesse pular a iteração de um dos estendidos?

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

A continuesempre se aplica ao escopo envolvente mais próximo, portanto você não pode usá-lo para interromper o loop mais externo. Se surgir uma condição como essa, você precisará fazer algo mais complicado, dependendo exatamente do que deseja, como breakno loop interno e depois continueno loop externo. Veja aqui a documentação sobre a breakpalavra - chave . A breakpalavra-chave C # é semelhante à lastpalavra-chave Perl .

Além disso, considere usar a sugestão de Dustin para filtrar previamente os valores que você não deseja processar:

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.
  }
}
John Feminella
fonte
Você poderia esclarecer melhor o que eu faria se tivesse feito o aninhamento de loops e quisesse ignorar a iteração de um dos estendidos? ex: para (int [] números em numberarrays) {for (int numero em números) {// O que fazer se quiser pular os (números / numberarrays)}}
Brian
C # gotoé realmente útil para a situação que @Brian está perguntando. Adicione um rótulo, como nextArray:na parte inferior do loop externo, e goto nextArray;quando desejar pular para ele.
precisa
55

Outra abordagem é filtrar usando LINQ antes da execução do loop:

foreach ( int number in numbers.Where(n => n >= 0) )
{
    // process number
}
Dustin Campbell
fonte
2
+1. Embora não seja uma resposta direta à pergunta, na prática eu provavelmente preferiria essa solução à que propus. Usar o LINQ parece ser um bom caso de uso geral para filtrar valores de loop que você não deseja processar.
31119 John Feminella
3
Isso é apenas mais arrumado ou será mais rápido, na medida em que há menos a prever? Eu estou supondo que o LINQ seja bastante otimizado, mas a seção LINQ terá que forçar em algum momento, portanto, teoricamente, se o conjunto de dados for grande e o subconjunto 'filtrado' resultante for quase o mesmo, será mais lento, pois um foreach deve ocorrer duas vezes? Então, talvez dependa do sub-conjunto de dados resultante esperado?
Coops
25

Você também pode inverter o seu teste if:


foreach ( int number in numbers )
{
     if ( number >= 0 )
     {
        //process number
     }
 }
crashmstr
fonte
:) Obrigado! Eu venho com um exemplo básico, porque havia alguns critérios no início do loop que não precisariam ser processados ​​e outros que eram erros que precisavam ser detectados.
Brian
4
A única resposta baseada em LINQ é boa e tem uma elegância, mas usar uma declaração if não está errado.
crashmstr
21
foreach ( int number in numbers )
{
    if ( number < 0 )
    {
        continue;
    }

    //otherwise process number
}
Tamas Czinege
fonte
16

Você pode usar a continuedeclaração

Por exemplo:

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

Outra abordagem usando o linq é:

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

Se você quiser pular o primeiro de vários itens.

Ou use .SkipWherese desejar especificar uma condição para ignorar.

Edmund Covington
fonte
Essa é a maneira mais simples (embora talvez a lógica interna seja a mesma) de fazer isso - agora que você tem o Linq disponível. Embora você deva garantir que o .Skip seja chamado apenas uma vez por motivos de desempenho. (Sim, agora vejo que essa não é a resposta direta à pergunta do OP, embora seja uma adição valiosa a esta lista de respostas). 1
B Charles H
8

Use a instrução continue:

foreach(object number in mycollection) {
     if( number < 0 ) {
         continue;
     }
  }
drewh
fonte
3
Não entendo por que ele é upvoted, isso é errado desde que ele loop sobre "o", não "número"
Fortune
Concordou, talvez esta seja uma cópia / pasta de respostas anteriores? Conceitualmente valioso, pois é um foreach, mas verifique se as variáveis ​​são consistentes.
Antonio Ciolino
0

A maneira mais fácil de fazer isso é como abaixo:

//Skip First Iteration

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

//Skip any other like 5th iteration

foreach ( int number in numbers.Skip(5))
Kashif
fonte