Break inner foreach loop and continue outer foreach loop

笑着哭i 提交于 2019-12-10 00:40:03

问题


If I have a nested foreach loop how do I do break the inner loop and tell the outer to continue at that point without doing any other code below the inner loop?

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();
}

回答1:


How about using a flag?

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

  DoStuff();
}



回答2:


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

  DoStuff();
  nextUpperLoop: ;
}



回答3:


Begin by writing a better version of Double.TryParse:

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

OK, now you have something you can easily use to eliminate the inner loop entirely, so the problem goes away:

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

Rather than try to figure out how to move control around, just write code that looks like the logic. If the logic is "don't do stuff if any of the other items do not parse as doubles", then use the Any predicate to test all the other items to see if any of them do not parse as doubles. No loops, so no fancy loop control needed.

I would be inclined to go a step further; capture the logic in a query, and then iterate the query:

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

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



回答4:


Simple is best...

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

Another approach is to refactor:

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

The return ensures the DoStuff doesn't happen.




回答5:


You need a variable to controll that and like you say.. do a 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();
}



回答6:


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();
}



回答7:


Iirc a break; statement will only break the closest loop, so issuing a break; in the inner loop should continue with the next item on the outer loop.




回答8:


It's not clear from your snippet, but if you only have to look for non-parseable values in otheritems then you can use LINQ:

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


来源:https://stackoverflow.com/questions/8168578/break-inner-foreach-loop-and-continue-outer-foreach-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!