What's the best way to break from nested loops in JavaScript?

JavascriptLoopsNested LoopsBreak

Javascript Problem Overview


What's the best way to break from nested loops in Javascript?

//Write the links to the page.
for (var x = 0; x < Args.length; x++)
{
   for (var Heading in Navigation.Headings)
   {
      for (var Item in Navigation.Headings[Heading])
      {
         if (Args[x] == Navigation.Headings[Heading][Item].Name)
         {
            document.write("<a href=\"" 
               + Navigation.Headings[Heading][Item].URL + "\">" 
               + Navigation.Headings[Heading][Item].Name + "</a> : ");
            break; // <---HERE, I need to break out of two loops.
         }
      }
   }
}

Javascript Solutions


Solution 1 - Javascript

Just like Perl,

loop1:
    for (var i in set1) {
loop2:
        for (var j in set2) {
loop3:
            for (var k in set3) {
                break loop2;  // breaks out of loop3 and loop2
            }
        }
    }

as defined in EMCA-262 section 12.12. [MDN Docs]

Unlike C, these labels can only be used for continue and break, as Javascript does not have goto.

Solution 2 - Javascript

Wrap that up in a function and then just return.

Solution 3 - Javascript

I'm a little late to the party but the following is a language-agnostic approach which doesn't use GOTO/labels or function wrapping:

for (var x = Set1.length; x > 0; x--)
{
   for (var y = Set2.length; y > 0; y--)
   {
      for (var z = Set3.length; z > 0; z--)
      {
          z = y = -1; // terminates second loop
          // z = y = x = -1; // terminate first loop
      }
   }
}

On the upside it flows naturally which should please the non-GOTO crowd. On the downside, the inner loop needs to complete the current iteration before terminating so it might not be applicable in some scenarios.

Solution 4 - Javascript

I realize this is a really old topic, but since my standard approach is not here yet, I thought I post it for the future googlers.

var a, b, abort = false;
for (a = 0; a < 10 && !abort; a++) {
    for (b = 0; b < 10 && !abort; b++) {
        if (condition) {
            doSomeThing();
            abort = true;
        }
    }
}

Solution 5 - Javascript

Quite simple:

var a = [1, 2, 3];
var b = [4, 5, 6];
var breakCheck1 = false;

for (var i in a) {
    for (var j in b) {
        breakCheck1 = true;
        break;
    }
    if (breakCheck1) break;
}

Solution 6 - Javascript

var str = "";
for (var x = 0; x < 3; x++) {
    (function() {  // here's an anonymous function
        for (var y = 0; y < 3; y++) {
            for (var z = 0; z < 3; z++) {
                // you have access to 'x' because of closures
                str += "x=" + x + "  y=" + y + "  z=" + z + "<br />";
                if (x == z && z == 2) {
                    return;
                }
            }
        }
    })();  // here, you execute your anonymous function
}

How's that? :)

Solution 7 - Javascript

Here are five ways to break out of nested loops in JavaScript:

1) Set parent(s) loop to the end

for (i = 0; i < 5; i++)
{
    for (j = 0; j < 5; j++)
    {
        if (j === 2)
        {
            i = 5;
            break;
        }
    }
}

2) Use label

exit_loops:
for (i = 0; i < 5; i++)
{
    for (j = 0; j < 5; j++)
    {
        if (j === 2)
            break exit_loops;
    }
}

3) Use variable

var exit_loops = false;
for (i = 0; i < 5; i++)
{
    for (j = 0; j < 5; j++)
    {
        if (j === 2)
        {
            exit_loops = true;
            break;
        }
    }
    if (exit_loops)
        break;
}

4) Use self executing function

(function()
{
    for (i = 0; i < 5; i++)
    {
        for (j = 0; j < 5; j++)
        {
             if (j === 2)
                 return;
        }
    }
})();

5) Use regular function

function nested_loops()
{
    for (i = 0; i < 5; i++)
    {
        for (j = 0; j < 5; j++)
        {
             if (j === 2)
                 return;
        }
    }
}
nested_loops();

Solution 8 - Javascript

How about using no breaks at all, no abort flags, and no extra condition checks. This version just blasts the loop variables (makes them Number.MAX_VALUE) when the condition is met and forces all the loops to terminate elegantly.

// No breaks needed
for (var i = 0; i < 10; i++) {
  for (var j = 0; j < 10; j++) {
    if (condition) {
      console.log("condition met");
      i = j = Number.MAX_VALUE; // Blast the loop variables
    }
  }
}

There was a similar-ish answer for decrementing-type nested loops, but this works for incrementing-type nested loops without needing to consider each loop's termination value for simple loops.

Another example:

// No breaks needed
for (var i = 0; i < 89; i++) {
  for (var j = 0; j < 1002; j++) {
    for (var k = 0; k < 16; k++) {
      for (var l = 0; l < 2382; l++) {
        if (condition) {
          console.log("condition met");
          i = j = k = l = Number.MAX_VALUE; // Blast the loop variables
        }
      }
    }
  }
}

Solution 9 - Javascript

If you use Coffeescript, there is a convenient "do" keyword that makes it easier to define and immediately execute an anonymous function:

do ->
  for a in first_loop
    for b in second_loop
      if condition(...)
        return

...so you can simply use "return" to get out of the loops.

Solution 10 - Javascript

How about pushing loops to their end limits

    for(var a=0; a<data_a.length; a++){
       for(var b=0; b<data_b.length; b++){
           for(var c=0; c<data_c.length; c++){
              for(var d=0; d<data_d.length; d++){
                 a =  data_a.length;
                 b =  data_b.length;
                 c =  data_b.length;
                 d =  data_d.length;
            }
         }
       }
     }

Solution 11 - Javascript

I thought I'd show a functional-programming approach. You can break out of nested Array.prototype.some() and/or Array.prototype.every() functions, as in my solutions. An added benefit of this approach is that Object.keys() enumerates only an object's own enumerable properties, whereas "a for-in loop enumerates properties in the prototype chain as well".

Close to the OP's solution:

	Args.forEach(function (arg) {
        // This guard is not necessary,
        // since writing an empty string to document would not change it.
		if (!getAnchorTag(arg))
			return;

		document.write(getAnchorTag(arg));
	});

	function getAnchorTag (name) {
		var res = '';

		Object.keys(Navigation.Headings).some(function (Heading) {
			return Object.keys(Navigation.Headings[Heading]).some(function (Item) {
				if (name == Navigation.Headings[Heading][Item].Name) {
					res = ("<a href=\""
								 + Navigation.Headings[Heading][Item].URL + "\">"
								 + Navigation.Headings[Heading][Item].Name + "</a> : ");
					return true;
				}
			});
		});

		return res;
	}

Solution that reduces iterating over the Headings/Items:

	var remainingArgs = Args.slice(0);

	Object.keys(Navigation.Headings).some(function (Heading) {
		return Object.keys(Navigation.Headings[Heading]).some(function (Item) {
			var i = remainingArgs.indexOf(Navigation.Headings[Heading][Item].Name);

			if (i === -1)
				return;

			document.write("<a href=\""
										 + Navigation.Headings[Heading][Item].URL + "\">"
										 + Navigation.Headings[Heading][Item].Name + "</a> : ");
			remainingArgs.splice(i, 1);

			if (remainingArgs.length === 0)
				return true;
			}
		});
	});

Solution 12 - Javascript

Already mentioned previously by swilliams, but with an example below (Javascript):

// Function wrapping inner for loop
function CriteriaMatch(record, criteria) {
  for (var k in criteria) {
    if (!(k in record))
      return false;

    if (record[k] != criteria[k])
      return false;
  }

  return true;
}

// Outer for loop implementing continue if inner for loop returns false
var result = [];

for (var i = 0; i < _table.length; i++) {
  var r = _table[i];

  if (!CriteriaMatch(r[i], criteria))
    continue;

  result.add(r);
}

Solution 13 - Javascript

Hmmm hi to the 10 years old party ?

Why not put some condition in your for ?

var condition = true
for (var i = 0 ; i < Args.length && condition ; i++) {
    for (var j = 0 ; j < Args[i].length && condition ; j++) {
        if (Args[i].obj[j] == "[condition]") {
            condition = false
        }
    }
}

Like this you stop when you want

In my case, using Typescript, we can use some() which go through the array and stop when condition is met So my code become like this :

Args.some((listObj) => {
    return listObj.some((obj) => {
        return !(obj == "[condition]")
    })
})

Like this, the loop stopped right after the condition is met

Reminder : This code run in TypeScript

Solution 14 - Javascript

There are many excellent solutions above. IMO, if your break conditions are exceptions, you can use try-catch:

try{  
    for (var i in set1) {
        for (var j in set2) {
            for (var k in set3) {
                throw error;
            }
        }
    }
}catch (error) {

}

Solution 15 - Javascript

Assign the values which are in comparison condition

function test(){
    for(var i=0;i<10;i++)
    {
            for(var j=0;j<10;j++)
            {
                    if(somecondition)
                    {
                            //code to Break out of both loops here
                            i=10;
                            j=10;
                    }
                    
            }
    }

    //Continue from here

}

Solution 16 - Javascript

XXX.Validation = function() {
    var ok = false;
loop:
    do {
        for (...) {
            while (...) {
                if (...) {
                    break loop; // Exist the outermost do-while loop
                }
                if (...) {
                    continue; // skips current iteration in the while loop
                }
            }
        }
        if (...) {
            break loop;
        }
        if (...) {
            break loop;
        }
        if (...) {
            break loop;
        }
        if (...) {
            break loop;
        }
        ok = true;
        break;
    } while(true);
    CleanupAndCallbackBeforeReturning(ok);
    return ok;
};

Solution 17 - Javascript

the best way is -

  1. Sort the both array which are used in first and second loop.
  2. if item matched then break the inner loop and hold the index value.
  3. when start next iteration start inner loop with hold index value.

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
QuestionGary WilloughbyView Question on Stackoverflow
Solution 1 - JavascriptephemientView Answer on Stackoverflow
Solution 2 - JavascriptswilliamsView Answer on Stackoverflow
Solution 3 - JavascriptaleembView Answer on Stackoverflow
Solution 4 - JavascriptzordView Answer on Stackoverflow
Solution 5 - JavascriptPaul Di BiaseView Answer on Stackoverflow
Solution 6 - Javascriptharley.333View Answer on Stackoverflow
Solution 7 - JavascriptDan BrayView Answer on Stackoverflow
Solution 8 - JavascriptDrakesView Answer on Stackoverflow
Solution 9 - JavascriptNick PerkinsView Answer on Stackoverflow
Solution 10 - Javascriptuser889030View Answer on Stackoverflow
Solution 11 - JavascriptZachary Ryan SmithView Answer on Stackoverflow
Solution 12 - JavascriptMatt BorjaView Answer on Stackoverflow
Solution 13 - JavascriptAzutanguyView Answer on Stackoverflow
Solution 14 - JavascriptTom ChenView Answer on Stackoverflow
Solution 15 - JavascriptPratik KhadtaleView Answer on Stackoverflow
Solution 16 - JavascriptTriquiView Answer on Stackoverflow
Solution 17 - JavascriptDeepak KarmaView Answer on Stackoverflow