打破内部foreach循环并继续外部foreach循环

Jon*_*Jon 25 .net c# .net-4.0 c#-4.0

如果我有一个嵌套的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();
}
Run Code Online (Sandbox Code Playgroud)

Tud*_*dor 37

用国旗怎么样?

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

  DoStuff();
}
Run Code Online (Sandbox Code Playgroud)


BLU*_*IXY 25

foreach(var item in items)
{
  foreach(var otheritem in otheritems)
  {
    if (!double.TryParse(otheritem))
    {
      //...
      goto nextUpperLoop;
    }
  }

  DoStuff();
  nextUpperLoop: ;
}
Run Code Online (Sandbox Code Playgroud)

  • @BLUEPIXY - 请不要光顾其他社区成员.对于你的第一个评论,这并不像任何人说"没有幽默标签".感谢您的合作,使这个社区更加友好. (7认同)
  • 这可能是goto的唯一合法用途。我更喜欢java通过标记循环来继续的方式。 (3认同)

Eri*_*ert 18

首先编写一个更好的Double.TryParse版本:

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

好的,现在你有一些东西可以很容易地用来完全消除内环,所以问题就消失了:

foreach(var item in items)
    if (!otheritems.Any(otherItem=>otherItem.TryParseDouble() == null))
        DoStuff();
Run Code Online (Sandbox Code Playgroud)

而不是试图弄清楚如何移动控制,只需编写看起来像逻辑的代码.如果逻辑是"如果任何其他项不解析为双精度,则不执行操作",则使用Any谓词测试所有其他项以查看其中任何项是否不解析为双精度.没有循环,因此不需要花哨的循环控制.

我倾向于更进一步; 捕获查询中的逻辑,然后迭代查询:

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

foreach(var goodItem in goodItems)
    DoStuff(goodItem);
Run Code Online (Sandbox Code Playgroud)

  • 好的建议,尽管它不能回答问题:如何在继续内部循环的同时在内循环中突围?在这种情况下,您可以将代码简化为一个循环,但是并非总是如此。 (2认同)

Mar*_*ell 12

简单就是最好的......

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

另一种方法是重构:

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

return确保DoStuff不会发生.


dkn*_*ack 5

你需要一个变量来控制,就像你说的那样......做一个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();
}
Run Code Online (Sandbox Code Playgroud)