ฉันจะข้ามการวนซ้ำของ foreach ได้อย่างไร


324

ใน Perl ฉันสามารถข้ามการวนซ้ำ foreach (หรือวนซ้ำใด ๆ ) ด้วยnext;คำสั่ง

มีวิธีข้ามการทำซ้ำและข้ามไปยังลูปถัดไปใน C # หรือไม่

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

     // otherwise process number
 }

การแจ้งผู้ใช้ที่อินพุตไม่ดีมีความสำคัญเท่ากับการข้ามไป!
UsefulBee

คำตอบ:


664

คุณต้องการ:

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

    // do work
}

ต่อไปนี้เป็นข้อมูลเพิ่มเติมเกี่ยวกับคำหลักcontinue


ปรับปรุง:เพื่อตอบสนองต่อคำถามติดตามของไบรอันในความคิดเห็น:

คุณช่วยอธิบายเพิ่มเติมสิ่งที่ฉันจะทำอย่างไรถ้าฉันซ้อนสำหรับลูปและต้องการข้ามการวนซ้ำของหนึ่งในการขยาย?

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

A continueใช้กับขอบเขตการปิดล้อมที่ใกล้ที่สุดเสมอดังนั้นคุณจึงไม่สามารถใช้เพื่อแยกวงลูปออกนอกสุด หากเงื่อนไขเช่นนั้นเกิดขึ้นคุณจะต้องทำสิ่งที่ซับซ้อนมากขึ้นโดยขึ้นอยู่กับสิ่งที่คุณต้องการเช่นbreakจากวงในและจากนั้นก็continueไปที่วงด้านนอก ดูที่นี่สำหรับเอกสารเกี่ยวกับที่คำหลักbreak breakC # คำหลักที่มีความคล้ายคลึงกับ Perl lastคำหลัก

นอกจากนี้ให้พิจารณาข้อเสนอแนะของดัสตินเพื่อกรองค่าที่คุณไม่ต้องการดำเนินการล่วงหน้า:

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

คุณช่วยอธิบายเพิ่มเติมสิ่งที่ฉันจะทำอย่างไรถ้าฉันซ้อนสำหรับลูปและต้องการข้ามการวนซ้ำของหนึ่งในการขยาย? เช่น: สำหรับ (int [] ตัวเลขใน numberarrays) {สำหรับ (int number เป็นตัวเลข) {// จะทำอย่างไรถ้าต้องการข้าม (ตัวเลข / numberarrays)}}
Brian

C # gotoมีประโยชน์จริง ๆ กับสถานการณ์ที่ @Brian กำลังถาม เพิ่มป้ายกำกับเช่นnextArray:ที่ด้านล่างของลูปด้านนอกแล้วgoto nextArray;เมื่อคุณต้องการข้ามไป
Jacob Krall

55

อีกวิธีคือการกรองโดยใช้ LINQ ก่อนที่ลูปประมวลผล:

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

2
+1 แม้ว่ามันจะไม่ใช่การตอบคำถามโดยตรง แต่ในทางปฏิบัติฉันอาจจะชอบวิธีนี้มากกว่าที่ฉันเสนอ การใช้ LINQ ดูเหมือนจะเป็นกรณีการใช้งานทั่วไปที่ดีสำหรับการกรองค่าลูปที่คุณไม่ต้องการดำเนินการ
John Feminella

3
นี่เป็นเพียงความเป็นระเบียบเรียบร้อยหรือจริง ๆ แล้วมันเร็วกว่าหรือว่าจะมีน้อยกว่า foreach? ฉันเดาว่า LINQ นั้นได้รับการปรับให้เหมาะสมที่สุด แต่ส่วน LINQ จะต้องมีในบางจุดดังนั้นในทางทฤษฎีถ้าชุดข้อมูลมีขนาดใหญ่และชุดย่อย 'ที่ถูกกรอง' ที่ได้จะมีขนาดใหญ่จนเกือบจะหมดแล้ว ครั้งที่สอง? ดังนั้นอาจขึ้นอยู่กับชุดข้อมูลย่อยผลลัพธ์ที่คาดหวัง
Coops

25

คุณสามารถพลิกถ้าทดสอบของคุณ:


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

:) ขอบคุณ! ฉันมาด้วยตัวอย่างพื้นฐานเพราะมีเกณฑ์บางอย่างในการเริ่มต้นของลูปที่ไม่จำเป็นต้องถูกประมวลผลและอื่น ๆ ที่มีข้อผิดพลาดที่จำเป็นต้องถูกจับ
Brian

4
คำตอบเดียวของ LINQ นั้นดีและมีความสง่างาม แต่การใช้คำสั่ง if นั้นไม่ผิด
crashmstr



16

อีกวิธีที่ใช้ linq คือ:

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

หากคุณต้องการข้ามรายการแรกในจำนวนรายการ

หรือใช้.SkipWhereถ้าคุณต้องการระบุเงื่อนไขสำหรับการข้าม


นี่เป็นวิธีที่ง่ายที่สุด (แม้ว่าตรรกะภายในอาจเหมือนกัน) ในการทำสิ่งนี้ - ตอนนี้คุณมี Linq ให้ใช้งานแล้ว แม้ว่าคุณควรแน่ใจว่า. Skip ถูกเรียกเพียงครั้งเดียวด้วยเหตุผลด้านประสิทธิภาพ (ใช่ฉันเห็นแล้วว่านี่ไม่ใช่คำตอบที่ตรงไปตรงมากับคำถามของ OP แม้ว่าจะเป็นการเพิ่มที่มีคุณค่าให้กับรายการคำตอบนี้) +1
B Charles H

8

ใช้คำสั่ง Continue:

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

3
ไม่เข้าใจว่าทำไม upvoted นี่เป็นสิ่งที่ผิดเนื่องจากเขาวนลูปมากกว่า "o" ไม่ใช่ "number"
Fortune

ตกลงอาจเป็นสำเนา / วางจากคำตอบก่อนหน้าหรือไม่ มีคุณค่าทางแนวคิดเนื่องจากเป็น foreach แต่โปรดตรวจสอบให้แน่ใจว่าตัวแปรสอดคล้องกัน
Antonio Ciolino

0

วิธีที่ง่ายที่สุดในการทำเช่นนี้คือ:

//Skip First Iteration

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

//Skip any other like 5th iteration

foreach ( int number in numbers.Skip(5))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.