34

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
  • 6
    I note that that's not the signature of double.TryParse. Commented Nov 17, 2011 at 14:36

8 Answers 8

46

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();
}
Sign up to request clarification or add additional context in comments.

Comments

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

  DoStuff();
  nextUpperLoop: ;
}

3 Comments

This is probably the only legitimate use of goto. I prefer java's way of continuing by labelling for loops though.
@BLUEPIXY I was just ranting in the tiny hope that Anders will read this and implement it in the next version of C#. Hope, a man can.
@BLUEPIXY - Please stop being patronizing towards other community members. It's not like anyone's saying "there's no humour tag" with regard to your first comment. Thank you for your cooperation in making this community more friendly.
21

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

1 Comment

Good advice, although it doesn't answer the question: how to break out of in inner loop, while continuing the outer? In this case you were able to simplify the code to a single loop, but that may not always be the case.
12

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.

Comments

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

Comments

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

Comments

0

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.

1 Comment

The OP wants to skip the remaining code on the outer loop and continue its execution at the top of the outer loop.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.