2011-11-17 3 views
16

Nếu tôi có vòng lặp forested lồng nhau làm cách nào để phá vỡ vòng lặp bên trong và yêu cầu bên ngoài tiếp tục tại điểm đó mà không làm bất kỳ mã nào khác bên dưới vòng lặp bên trong?Break vòng lặp foreach bên trong và tiếp tục vòng lặp foreach bên ngoài

foreach(var item in items) 
{ 
    foreach(var otheritem in otheritems) 
    { 
    if (!double.TryParse(otheritem)) 
    { 
     //break inner loop 
     //continue outer loop so we never get to DoStuff() 
    } 
    } 

    DoStuff(); 
} 
+6

Tôi lưu ý rằng đó không phải là chữ ký của double.TryParse. –

Trả lời

28

Làm thế nào về việc sử dụng một lá cờ?

foreach(var item in items) 
{ 
    bool flag = false; 
    foreach(var otheritem in otheritems) 
    { 
    if (!double.TryParse(otheritem)) 
    { 
     flag = true; 
     break; 
    } 
    } 
    if(flag) continue; 

    DoStuff(); 
} 
4

Bạn cần một biến để kiểm soát và giống như bạn nói .. làm break.

bool doStuff = true; 
foreach(var item in items) 
{ 
    doStuff = true; 
    foreach(var otheritem in otheritems) 
    { 
    if (!double.TryParse(otheritem)) 
    { 
     doStuff = false; 
     break; 
    } 
    } 

    if (doStuff) 
     DoStuff(); 
} 
3
foreach(var item in items) 
{ 
    var shouldContinue = false; 

    foreach(var otheritem in otheritems) 
    { 
    if (!double.TryParse(otheritem)) 
    { 
     shouldContinue = true; 
     //break inner loop 
     //continue outer loop so we never get to DoStuff() 
    } 
    } 

    if(shouldContinue) 
    continue; 

    DoStuff(); 
} 
9

Đơn giản là tốt nhất ...

bool doStuff = true; 
    foreach(var otheritem in otheritems) 
    { 
    if (!double.TryParse(otheritem)) 
    { 
     doStuff = false; 
     break; 
    } 
    } 
    if(doStuff) DoStuff(); 

cách tiếp cận khác là để cấu trúc lại:

foreach(var outerItem in outerLoop) { 
    Foo(outerItem); 
} 
... 
void Foo(OuterItem item) { 
    foreach(var innerItem in innerLoop) { 
     if(someTest) return; 
    } 
    DoStuff(); 
} 

Các return đảm bảo DoStuff không xảy ra.

0

Iirc ngắt; tuyên bố sẽ chỉ phá vỡ vòng lặp gần nhất, do đó, phát hành một break; trong vòng lặp bên trong nên tiếp tục với mục tiếp theo trên vòng lặp bên ngoài.

+1

OP muốn bỏ qua mã còn lại trên vòng lặp bên ngoài và tiếp tục thực thi ở đầu vòng lặp bên ngoài. –

0

Nó không rõ ràng từ đoạn mã của bạn, nhưng nếu bạn chỉ cần tìm kiếm các giá trị phi parseable trong otheritems sau đó bạn có thể sử dụng LINQ:

foreach(var item in items) 
{ 
    bool shouldISkip = otheritems.Any(otherItem => !double.TryParse(otherItem)); 
    if(shouldISkip) continue; 
    DoStuff(); 
} 
17
foreach(var item in items) 
{ 
    foreach(var otheritem in otheritems) 
    { 
    if (!double.TryParse(otheritem)) 
    { 
     //... 
     goto nextUpperLoop; 
    } 
    } 

    DoStuff(); 
    nextUpperLoop: ; 
} 
+5

+1 chỉ để táo bạo sử dụng goto. –

+2

vâng, tất cả mọi người cố gắng tránh sử dụng goto morbidly. kinh tởm ... – BLUEPIXY

+1

Đây có lẽ là cách sử dụng hợp pháp duy nhất của goto. Tôi thích cách tiếp tục của java bằng cách ghi nhãn cho các vòng mặc dù. – arviman

18

Bắt đầu bằng cách viết một phiên bản tốt hơn của Double. TryParse:

static double? TryParseDouble(this string s) 
{ 
    double d; 
    return double.TryParse(s, out d) ? (double?)d : (double?)null; 
} 

OK, bây giờ bạn có một cái gì đó bạn có thể dễ dàng sử dụng để loại bỏ các vòng lặp bên trong hoàn toàn, vì vậy vấn đề đi xa:

foreach(var item in items) 
    if (!otheritems.Any(otherItem=>otherItem.TryParseDouble() == null)) 
     DoStuff(); 

Thay vì cố gắng tìm ra cách di chuyển kiểm soát xung quanh, chỉ cần viết mã trông giống như logic. Nếu logic là "không làm công cụ nếu bất kỳ các mục khác không phân tích cú pháp như tăng gấp đôi", sau đó sử dụng bất kỳ vị ngữ để kiểm tra tất cả các mặt hàng khác để xem nếu bất kỳ trong số họ không phân tích cú đúp. Không có vòng lặp, do đó không cần điều khiển vòng lặp lạ mắt.

Tôi sẽ có khuynh hướng tiến thêm một bước; nắm bắt logic trong truy vấn và sau đó lặp lại truy vấn:

var goodItems = from item in items 
       where !item.OtherItems.Any(otherItem=>otherItem.TryParseDouble() == null)) 
       select item; 

foreach(var goodItem in goodItems) 
    DoStuff(goodItem); 
+1

Lời khuyên tốt, mặc dù nó không trả lời câu hỏi: làm thế nào để thoát ra khỏi vòng lặp bên trong, trong khi tiếp tục bên ngoài? Trong trường hợp này, bạn có thể đơn giản hóa mã thành một vòng lặp, nhưng điều đó có thể không phải lúc nào cũng đúng. – Kokodoko