Thanks
Thanks

Reputation: 40329

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

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.

Upvotes: 76

Views: 63494

Answers (13)

Tom Howard
Tom Howard

Reputation: 4908

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

Upvotes: 0

Martin
Martin

Reputation: 11

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

Upvotes: 0

Martijn
Martijn

Reputation: 12092

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

Upvotes: 2

lothar
lothar

Reputation: 20209

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

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

Upvotes: 9

Ori Pessach
Ori Pessach

Reputation: 6833

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

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

Upvotes: 109

Yogi
Yogi

Reputation: 2540

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

Upvotes: 2

jbasko
jbasko

Reputation: 7330

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

Upvotes: 95

George Armhold
George Armhold

Reputation: 31064

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.

Upvotes: 7

unwind
unwind

Reputation: 399793

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. */
    }
  }
}

Upvotes: 14

oxigen
oxigen

Reputation: 6263

Change top loop's counter before break

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

Upvotes: 2

Lance Richardson
Lance Richardson

Reputation: 4610

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.

Upvotes: 1

Nick Allen
Nick Allen

Reputation: 12220

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

Upvotes: 4

Mitch Wheat
Mitch Wheat

Reputation: 300529

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)

Upvotes: 0

Related Questions