Làm thế nào để tôi bỏ qua một vòng lặp của vòng lặp `foreach`?


324

Trong Perl tôi có thể bỏ qua một lần lặp foreach (hoặc bất kỳ vòng lặp) nào bằng một next;lệnh.

Có cách nào để bỏ qua một lần lặp và nhảy sang vòng lặp tiếp theo trong C # không?

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

     // otherwise process number
 }

Thông báo cho người dùng với đầu vào xấu của họ cũng quan trọng như bỏ qua nó!
hữu íchBee

Câu trả lời:


664

Bạn muốn:

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

    // do work
}

Đây là nhiều hơn về continuetừ khóa .


Cập nhật: Trả lời câu hỏi tiếp theo của Brian trong các bình luận:

Bạn có thể làm rõ hơn những gì tôi sẽ làm nếu tôi đã lồng vào các vòng lặp và muốn bỏ qua việc lặp lại một trong những vòng mở rộng?

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

A continueluôn áp dụng cho phạm vi bao quanh gần nhất, vì vậy bạn không thể sử dụng nó để thoát ra khỏi vòng lặp ngoài cùng. Nếu một điều kiện như vậy phát sinh, bạn cần phải làm một cái gì đó phức tạp hơn tùy thuộc vào chính xác những gì bạn muốn, như breaktừ vòng lặp bên trong, sau đó continuevào vòng lặp bên ngoài. Xem ở đây để các tài liệu về breaktừ khóa . Các breakC # từ khóa tương tự như Perl lasttừ khóa.

Ngoài ra, hãy xem xét lấy đề xuất của Dustin để chỉ lọc ra các giá trị bạn không muốn xử lý trước:

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

Bạn có thể làm rõ hơn những gì tôi sẽ làm nếu tôi đã lồng vào các vòng lặp và muốn bỏ qua việc lặp lại một trong những vòng mở rộng? ex: for (int [] number in numberarrays) {for (int number in number) {// Phải làm gì nếu muốn nhảy (số / numberarrays)}}
Brian

C # gotothực sự hữu ích cho tình huống mà @Brian đang hỏi về. Thêm một nhãn như nextArray:ở dưới cùng của vòng lặp bên ngoài, và sau đó goto nextArray;khi bạn muốn bỏ qua nó.
Jacob Krall

55

Một cách tiếp cận khác là lọc bằng LINQ trước khi vòng lặp thực thi:

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

2
+1. Mặc dù đó không phải là câu trả lời trực tiếp cho câu hỏi, nhưng trong thực tế tôi có lẽ thích giải pháp này hơn giải pháp tôi đề xuất. Sử dụng LINQ có vẻ như là một trường hợp sử dụng chung tốt để lọc ra các giá trị vòng lặp mà bạn không muốn xử lý.
John Women'sella 17/03/2016

3
Đây chỉ là gọn gàng hơn hay nó sẽ thực sự nhanh hơn trong đó có ít để nghiên cứu? Tôi đoán rằng LINQ được tối ưu hóa rất nhiều nhưng phần LINQ sẽ phải thảo luận vào một lúc nào đó vì vậy về mặt lý thuyết nếu tập dữ liệu lớn và tập hợp con 'được lọc' gần như lớn, thì điều này sẽ chậm hơn khi xảy ra một cuộc thảo luận hai lần? Vì vậy, có thể nó phụ thuộc vào dữ liệu phụ kết quả dự kiến?
Coops

25

Bạn cũng có thể lật bài kiểm tra nếu:


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

:) Cảm ơn! Tôi đưa ra một ví dụ cơ bản vì có một số tiêu chí ở đầu vòng lặp không cần xử lý và những tiêu chí khác là lỗi cần phải bắt.
Brian

4
Câu trả lời dựa trên LINQ là hay và có một sự tao nhã đối với nó, nhưng sử dụng câu lệnh if không sai.
crashmstr

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

    //otherwise process number
}

16

Bạn có thể sử dụng continuetuyên bố.

Ví dụ:

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

16

Một cách tiếp cận khác sử dụng linq là:

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

Nếu bạn muốn bỏ qua đầu tiên trong một số mặt hàng.

Hoặc sử dụng .SkipWherenếu bạn muốn chỉ định một điều kiện để bỏ qua.


Đây là cách đơn giản nhất (mặc dù có thể logic bên trong giống như vậy) để thực hiện việc này - bây giờ bạn đã có sẵn Linq. Mặc dù bạn nên đảm bảo rằng .Skip chỉ được gọi một lần vì lý do hiệu suất. (Vâng, tôi thấy bây giờ đây không phải là câu trả lời thẳng cho câu hỏi của OP, mặc dù đây là một bổ sung có giá trị vào danh sách câu trả lời này). +1
B Charles H

8

Sử dụng câu lệnh tiếp tục:

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

3
Không hiểu tại sao nó được nâng cấp, điều này là sai vì anh ta lặp qua "o", không phải "số"
Fortune

Đồng ý, có lẽ đây là một bản sao / dán từ các câu trả lời trước? Về mặt khái niệm có giá trị vì nó là một hướng dẫn, nhưng vui lòng đảm bảo các biến là nhất quán.
Antonio Ciolino

0

Cách dễ nhất để làm điều đó là như dưới đây:

//Skip First Iteration

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

//Skip any other like 5th iteration

foreach ( int number in numbers.Skip(5))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.