2011-11-17 225 views
16

如果我有一個嵌套的foreach循環我該怎麼做中斷內部循環,並告訴外部繼續在那一點上沒有做任何其他代碼內部循環?打破內部的foreach循環,並繼續外部的foreach循環

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

我注意到那不是double.TryParse的簽名。 –

回答

28

如何使用標誌?

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

你需要一個變量來控制,並且像你說的那樣..做一個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

簡單就是最好的...

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

另一種方法是重構:

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

return確保DoStuff不會發生。

0

Iirc a break;聲明只會打破最接近的循環,因此發出休息;在內循環中應該繼續外循環中的下一項。

+1

OP想要跳過外循環中的剩餘代碼並在外循環的頂部繼續執行它。 –

0

這不是從你的片段清晰,但如果你只需要看看非解析的值otheritems那麼你可以使用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只是爲了敢於使用goto。 –

+2

是的,每個人都試圖避免使用goto morbidly。噁心...... – BLUEPIXY

+1

這可能是goto的唯一合法使用。儘管如此,我更喜歡Java繼續標記循環的方式。 – arviman

18

通過寫一個更好的版本雙重的開始。的TryParse:

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

OK,現在你有什麼事情,你可以很容易地使用完全消除了內部循環,使問題消失:

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

與其試圖弄清楚如何移動控制,只是編寫看起來像邏輯的代碼。如果邏輯是「如果任何其他項目不解析爲雙打,則不做任何事情」,然後使用Any謂詞測試所有其他項目以查看它們中的任何項目是否不解析爲雙打。沒有循環,所以不需要花哨的循環控制。

我會傾向於更進一步;捕獲查詢中的邏輯,然後遍歷查詢:

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

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

很好的建議,雖然它沒有回答這個問題:如何在內部循環中突圍,同時繼續外部?在這種情況下,您可以將代碼簡化爲單個循環,但情況並非總是如此。 – Kokodoko