Problem
How can I get out of both loops (inner and outer) as quickly as possible if I have a for loop that is nested within another?
I don’t want to use a boolean and then say proceed to another function; instead, I just want to run the first line of code after the outer loop.
Is there a quick and pleasant way to do this?
I was thinking that exceptions aren’t cheap, and that they should only be made in genuinely extraordinary circumstances. As a result, I don’t believe this option would be good in terms of performance.
I don’t believe it is appropriate to use one of.newer NET’s capabilities (anon methods) to do something so basic.
Asked by GurdeepS
Solution #1
Okay, that’s OK, but it’s unsightly and not always possible. You may alternatively put the loops in a method (or an anon-method) and escape back to the main code using return.
// goto
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
goto Foo; // yeuck!
}
}
Foo:
Console.WriteLine("Hi");
vs:
// anon-method
Action work = delegate
{
for (int x = 0; x < 100; x++)
{
for (int y = 0; y < 100; y++)
{
return; // exits anon-method
}
}
};
work(); // execute anon-method
Console.WriteLine("Hi");
It’s worth noting that in C# 7, we should have “local functions,” which (syntax tbd etc) means it should behave like this:
// local function (declared **inside** another method)
void Work()
{
for (int x = 0; x < 100; x++)
{
for (int y = 0; y < 100; y++)
{
return; // exits local function
}
}
};
Work(); // execute local function
Console.WriteLine("Hi");
Answered by Marc Gravell
Solution #2
Set the value of the outer loop’s variable outside of loop conditions in C# (i.e. for loops utilizing int variables, INT MAX -1 is frequently a good choice):
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
if (exit_condition)
{
// cause the outer loop to break:
// use i = INT_MAX - 1; otherwise i++ == INT_MIN < 100 and loop will continue
i = int.MaxValue - 1;
Console.WriteLine("Hi");
// break the inner loop
break;
}
}
// if you have code in outer loop it will execute after break from inner loop
}
Break will not magically jump to the next iteration of the outer loop, as noted in the code, thus if you have code outside of the inner loop, this technique will require more checks. In this scenario, think about other options.
This method works with for, while, and foreach loops, but not with foreach. You won’t have code access to the hidden enumerator in case of foreach, thus you won’t be able to change it (and even if you did, IEnumerator doesn’t have a “MoveToEnd” method).
Authors of inlined comments are thanked: I = INT MAX – 1 Meta recommendation for/foreach remark by ygoe jmbpiano’s proper IntMax and blizpasta’s statement about code after the inner loop
Answered by Nils Pipenbrinck
Solution #3
This solution isn’t applicable to C#.
Javascript, Java, and D provide labeled breaks and continues for those who encountered this question through other languages:
outer: while(fn1())
{
while(fn2())
{
if(fn3()) continue outer;
if(fn4()) break outer;
}
}
Answered by BCS
Solution #4
In the outer loop, use a suitable protection. Before you break, place the guard in the inner loop.
bool exitedInner = false;
for (int i = 0; i < N && !exitedInner; ++i) {
.... some outer loop stuff
for (int j = 0; j < M; ++j) {
if (sometest) {
exitedInner = true;
break;
}
}
if (!exitedInner) {
... more outer loop stuff
}
}
Better yet, make the inner loop into a method and call it when the outer loop returns false.
for (int i = 0; i < N; ++i) {
.... some outer loop stuff
if (!doInner(i, N, M)) {
break;
}
... more outer loop stuff
}
Answered by tvanfosson
Solution #5
Don’t take my word for it, but according to MSDN, you could use goto. There are additional options, such as using a flag that is verified in each loop iteration. Finally, as a really heavyweight solution to the problem, you may utilize an exception.
GOTO:
for ( int i = 0; i < 10; ++i ) {
for ( int j = 0; j < 10; ++j ) {
// code
if ( break_condition ) goto End;
// more code
}
}
End: ;
Condition:
bool exit = false;
for ( int i = 0; i < 10 && !exit; ++i ) {
for ( int j = 0; j < 10 && !exit; ++j ) {
// code
if ( break_condition ) {
exit = true;
break; // or continue
}
// more code
}
}
Exception:
try {
for ( int i = 0; i < 10 && !exit; ++i ) {
for ( int j = 0; j < 10 && !exit; ++j ) {
// code
if ( break_condition ) {
throw new Exception()
}
// more code
}
}
catch ( Exception e ) {}
Answered by David RodrÃguez – dribeas
Post is based on https://stackoverflow.com/questions/324831/breaking-out-of-a-nested-loop