6

I have a while loop in which I have two for loops. I have a condition in the innermost for loop. Whenever that condition is satisfied I want to exit from both the two for loops and continue within the while loop:

while (1)
    for x=1:20
        for y=1:30
            if(condition)

            end
        end
    end
end

Does Matlab have something like a labeled statement in Java, or is there another way to do this?

Daniel
  • 36,610
  • 3
  • 36
  • 69
Amit Kumar
  • 5,888
  • 11
  • 47
  • 85
  • possible duplicate of [Can a Matlab M-script be stopped by a statement in the script?](http://stackoverflow.com/questions/15146643/can-a-matlab-m-script-be-stopped-by-a-statement-in-the-script) – bla Nov 30 '13 at 17:00
  • 1
    Depending on how your code is organized, you could wrap the loops in a function and `return` whenever the condition is met – tmpearce Nov 30 '13 at 17:06
  • 1
    @natan I don't think it's a duplicate of that – Luis Mendo Nov 30 '13 at 17:10
  • related link: [How do I break out of nested loops using the BREAK command in MATLAB 7.7 (R2008b)?](http://www.mathworks.com/matlabcentral/answers/102711) – Eitan T Dec 01 '13 at 13:23
  • Amit Kumar, @LuisMendo, check out my new solution. :-) – A. Donda Dec 01 '13 at 19:57
  • I assume you just want to have a way to make sure the if is only reached once, and do this with good performance? Or are you actually interested in the values of `x` and `y` after the loop is broken? – Dennis Jaheruddin Dec 01 '13 at 20:25

7 Answers7

7

One ever so slightly more elegant way than Luis Mendo's. ;-)

while (1)
    for x=1:20
        for y=1:30
            quit = (condition);
            if quit
                break;
            end
        end
        if quit
            break;
        end
    end
end
A. Donda
  • 8,381
  • 2
  • 20
  • 49
5

Only slightly more elegant than A.Donda's answer (avoids testing the condition twice):

while 1
    for x=1:20
        for y=1:30
            quit = 0;
            if (condition)
                quit = 1;
                break;
            end
        end
        if quit
            break;
        end
    end
end
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
  • While it does avoid testing the condition twice, it adds (quite a lot of) extra tests for `quit`... – Eitan T Dec 01 '13 at 13:27
  • @EitanT "Extra" compared to what? You either test for `quit` or for the condition (which takes longer), right? – Luis Mendo Dec 01 '13 at 15:55
  • 1
    Compared to, say, your solution that "flattens" the loop and uses `ndgrid`. There's no need to test `quit` in every loop iteration, you're already testing for the condition. – Eitan T Dec 01 '13 at 16:08
  • @EitanT You mean in every iteration of the _outer_ lopp, right? Yes, you could save that. However, the bottleneck here would be testing within the inner loop (which is done 30 times more often), and that would not be avoided. – Luis Mendo Dec 01 '13 at 16:17
  • I am obviously talking about the outer loop :) I think that the numbers are arbitrary, and the flattened-loop solution is a safer bet in any case. But I'm just nitpicking. – Eitan T Dec 01 '13 at 16:20
  • @EitanT Agree that the flattened-loop is better. But that approach is easy only if the outer loop does nothing except running the inner loop -- which is not obvious from the problem specification. And thanks for your comments :-) – Luis Mendo Dec 01 '13 at 16:23
4

Here is a very simple answer leveraging the fact that testing numerous simple conditions is nearly free:

while (1)
    go = true;
    for x=1:20
        for y=1:30
            if go && condition
               go = false;

            end
        end
    end
end

This approach is very simple, easily generalized to any number of loops and avoids the abuse of error handling.

Dennis Jaheruddin
  • 21,208
  • 8
  • 66
  • 122
2

A bit of abuse, a bit of overkill, but here it is: yet another way

while (1)
    try
        for x = 1 : 20
            for y = 1 : 30
                assert(~(condition), 'break')
            end
        end
    catch err
        if ~strcmp(err.message, 'break'), rethrow(err), end
    end
end

The nice thing about this approach is that it works with an arbitrary number of nested loops, and only evaluates condition once without having to store the result in a variable.

Inspired by tmpearce's comment.

A. Donda
  • 8,381
  • 2
  • 20
  • 49
1

I'm aware of only one quite inelegant way to do this: check the condition twice.

while (1)
    for x=1:20
        for y=1:30
            if (condition)
                break;
            end
        end
        if (condition)
            break;
        end
    end
end
A. Donda
  • 8,381
  • 2
  • 20
  • 49
1

Another possibility, which avoids using two break statements: if you don't do anything in the outer for loop except calling the inner for loop, you can merge them:

[yy xx] = ndgrid(1:20,1:30);
while 1
    for n = 1:numel(x)
        x = xx(n);
        y = yy(n);
        if (condition)
            break      
        end
    end
end
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
0

immediate exit for both for loops and continue with the remain of while loop.

while (1)
    go=1 %

    for x=1:20
        if go==0;break; %

        for y=1:30
            if(condition)
                go=0;break; %
            end
        end
    end
end
zlin
  • 195
  • 2
  • 11