Bir "foreach" döngüsünün yinelemesini nasıl atlarım?


324

Perl'de bir next;komut ile bir foreach (veya herhangi bir loop) yinelemesini atlayabilirim .

Bir yineleme atlamak ve C # sonraki döngü atlamak için bir yolu var mı?

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

     // otherwise process number
 }

Kullanıcıya hatalı girdilerini bildirmek, atlamak kadar önemlidir!
usefulBee

Yanıtlar:


664

İstediğiniz:

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

    // do work
}

continueAnahtar kelime hakkında daha fazla bilgi .


Güncelleme: Brian'ın yorumlardaki takip sorusuna yanıt olarak:

Döngüler için iç içe geçmiş olsaydım ve genişletilmiş olanlardan birinin yinelemesini atlamak istersem ne yapacağımı daha açıklayabilir misiniz?

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

A continueher zaman en yakın çevreleme kapsamı için geçerlidir, bu nedenle en dıştaki döngüden çıkmak için kullanamazsınız. Böyle bir durum ortaya çıkarsa break, iç döngüden, ardından continuedış döngüden tam olarak ne istediğinize bağlı olarak daha karmaşık bir şey yapmanız gerekir . breakAnahtar kelime ile ilgili belgeler için buraya bakın . breakC # anahtar kelime Perl benzer lastanahtar kelime.

Ayrıca, önceden işlemek istemediğiniz değerleri filtrelemek için Dustin'in önerisini almayı düşünün:

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

Döngüler için iç içe geçmiş olsaydım ve genişletilmiş olanlardan birinin yinelemesini atlamak istersem ne yapacağımı daha açıklayabilir misiniz? örnek: for (numberarrays içindeki int [] sayıları) {for (sayıdaki int sayısı) {// (numbers / numberarrays) atlamak istiyorsanız ne yapmalı}}
Brian

C # 'ın goto@Brian'ın sorduğu durum için gerçekten yararlıdır. nextArray:Dış halkanın altına ve ardından goto nextArray;atlamak istediğinizde olduğu gibi bir etiket ekleyin .
Jacob Krall

55

Başka bir yaklaşım, döngü yürütülmeden önce LINQ kullanarak filtrelemektir:

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

2
+1. Bu soruya doğrudan bir cevap olmamasına rağmen, pratikte muhtemelen bu çözümü önerdiğim çözüme tercih ederim. LINQ kullanmak, işlemek istemediğiniz döngü değerlerini filtrelemek için iyi bir genel kullanım durumu gibi görünür.
John Feminella

3
Bu sadece daha düzenli mi, yoksa daha az öngörü olması gerektiğinden daha hızlı mı olacak? LINQ büyük ölçüde optimize edilmiş ama veri kümesi büyük ve sonuçta 'filtre' alt küme neredeyse büyükse, teorik olarak LINQ bölümünün bir noktada foreach zorunda kalacağını tahmin ediyorum iki defa? Belki de beklenen sonuç alt veri kümesine bağlıdır?
Coops

25

Ayrıca if testinizi çevirebilirsiniz:


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

:) Teşekkürler! Ben temel bir örnek ile geldim çünkü döngü başında işlenmesi gerekmeyen bazı kriterler ve diğerleri yakalanması gereken hatalar vardı.
Brian

4
Bir LINQ tabanlı cevap güzel ve bir zerafet vardır, ancak bir if ifadesi kullanmak yanlış değildir.
crashmstr

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

    //otherwise process number
}

16

İfadeyi kullanabilirsiniz continue.

Örneğin:

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

16

Linq kullanan bir başka yaklaşım:

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

Birkaç öğede ilkini atlamak istiyorsanız.

Veya .SkipWhereatlama için bir koşul belirtmek istiyorsanız kullanın.


Bu en basit (belki de içindeki mantık aynı olsa da) bunu yapmanın yolu - şimdi Linq'iniz var. Gerçi .Skip'in performans nedenleriyle yalnızca bir kez çağrıldığından emin olmalısınız. (Evet, şimdi görüyorum ki bu OP'nin sorusuna doğrudan bir cevap değil, ancak bu cevap listesine değerli bir ek). +1
B Charles H

8

Continue ifadesini kullanın:

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

3
Neden değerlendirildiğini anlamıyorum, çünkü o "sayı" değil, "o" üzerinde döngü çünkü bu yanlış
Fortune

Kabul ettiniz, belki bu önceki cevaplardan bir kopya / yapıştır? Öngörülü olduğu için kavramsal olarak değerli, ancak lütfen değişkenlerin tutarlı olduğundan emin olun.
Antonio Ciolino

0

Bunu yapmanın en kolay yolu aşağıdaki gibidir:

//Skip First Iteration

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

//Skip any other like 5th iteration

foreach ( int number in numbers.Skip(5))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.