How can I break out of two nested for loops in Objective-C?

CObjective CLoops

C Problem Overview


I have two for loops nested like this:

for(...) {
	for(...) {

	}
}

I know that there is a break statement. But I am confused about if it breaks both loops or just the one in which it was called? I need to break both ones as soon as I see that it doesn't make sense to iterate more times over.

C Solutions


Solution 1 - C

If using goto simplifies the code, then it would be appropriate.

for (;;) 
{
    for (;;) 
    {
        break; /* breaks inner loop */
    } 
    for (;;) 
    {
        goto outer; /* breaks outer loop */
    }
} 
outer:;

Solution 2 - C

break breaks out of one loop, but you can add a check to the outer loop which breaks when the inner breaks.

bool dobreak = false;
for ( ..; !dobreak && ..; .. ) {
   for ( ... ) {
      if (...) {
         dobreak = true;
         break;
      }
   }
}

Solution 3 - C

The break statement only gets you out of the innermost loop. If you don't want the added overhead in code, memory and performance of a dedicated state variable, I recommend refactoring the code out into a function or method of its own, and using return to get out of all the loops:

void do_lots_of_work(void)
{
  int i, j;

  for(i=0; i<10 ; i++)
  {
    for(j=0;j< 10; j++)
    {
     ..
     ..
     if(disaster_struck())
      return; /* Gets us out of the loops, and the function too. */
    }
  }
}

Solution 4 - C

Other than the already mentioned flag variable or goto you could throw an Objective-C exception:

@try {
  for() {
    for() {
       @throw ...
    }
  }
}
@catch{
  ...
}

Solution 5 - C

Others have mentioned how you can set a flag or use a goto, but I'd recommend refactoring your code so that the inner loop is turned into a separate method. That method can then return some flag to indicate that the outer loop should break. If you name your methods appropriately, this is much more readable.

for (int i = 0; i < 10; i++) {
   if (timeToStop(i)) break;
}

-(bool) timeToStop: (int) i {
    for (int j = 0; j < 10; j++) {
        if (somethingBadHappens) return true;
    }

    return false;
}

Pseudocode, not tested, but you get the idea.

Solution 6 - C

The break statement will only break out of the loop in scope, which is the parent loop. If you want to break out of the second loop as well you could use a boolean variable which is in scope of both loops

bool isTerminated = false;

for (...)
{
    if (!isTerminated)
    {
        for(...)
        {
            ...

            isTerminated = true;
            break;
        }
    }
    else
    {
        break;
    }
}

Solution 7 - C

Probably the easiest way is to use a "flag" variable

for(i=0; i<10 && (done==false); i++)
  for(j=0;j< 10; j++){
     ..
     ..
     if(...){done=true; break;}
  }

Solution 8 - C

Change top loop's counter before break

for(i=0; i<10 ; i++)
  for(j=0;j< 10; j++){
     ..
     ..
     i = 10; 
     break;
  }

Solution 9 - C

Another solution is to factor out the second loop in a function:

int i;

for(i=0; i<10 ; i++){
    if !innerLoop(i) {
        break;
    }
}

bool innerLoop(int i)
    int j;
    for(j=0;j< 10; j++){
        doSomthing(i,j);
        if(endcondtion){
            return false;
        }
    }
}

Solution 10 - C

The break statement breaks out of the innermost loop. An additional test and break statement would be needed to break out of the outer loop.

Solution 11 - C

If a break is executed from within a set of nested loops, only the innermost loop in which the break is executed is terminated. (Just like standard C)

Solution 12 - C

Exactly like the last ones are, generally like this:

for(i=0;i<a;i++){  
 for(j=0;j<a;j++){
  if(Something_goes_wrong){
   i=a;
   break;
   }
 }
}

Solution 13 - C

Just for grins, how about changing this true/false check into a method and using return statements:

- (bool) checkTrueFalse: parameters{

   for ( ...) {
      for ( ... ) {

         if (...) {
            return true;
         }

      }
   }
   return false;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThanksView Question on Stackoverflow
Solution 1 - COri PessachView Answer on Stackoverflow
Solution 2 - CjbaskoView Answer on Stackoverflow
Solution 3 - CunwindView Answer on Stackoverflow
Solution 4 - ClotharView Answer on Stackoverflow
Solution 5 - CGeorge ArmholdView Answer on Stackoverflow
Solution 6 - CNick AllenView Answer on Stackoverflow
Solution 7 - CYogiView Answer on Stackoverflow
Solution 8 - CoxigenView Answer on Stackoverflow
Solution 9 - CMartijnView Answer on Stackoverflow
Solution 10 - CLance RichardsonView Answer on Stackoverflow
Solution 11 - CMitch WheatView Answer on Stackoverflow
Solution 12 - CMartinView Answer on Stackoverflow
Solution 13 - CTom HowardView Answer on Stackoverflow