Advertisement
Advertisement


Short circuit Array.forEach like calling break


Question

[1,2,3].forEach(function(el) {
    if(el === 1) break;
});

How can I do this using the new forEach method in JavaScript? I've tried return;, return false; and break. break crashes and return does nothing but continue iteration.

2018/09/21
1
1648
9/21/2018 2:47:39 PM

Accepted Answer

There's no built-in ability to break in forEach. To interrupt execution you would have to throw an exception of some sort. eg.

var BreakException = {};

try {
  [1, 2, 3].forEach(function(el) {
    console.log(el);
    if (el === 2) throw BreakException;
  });
} catch (e) {
  if (e !== BreakException) throw e;
}

JavaScript exceptions aren't terribly pretty. A traditional for loop might be more appropriate if you really need to break inside it.

Use Array#some

Instead, use Array#some:

[1, 2, 3].some(function(el) {
  console.log(el);
  return el === 2;
});

This works because some returns true as soon as any of the callbacks, executed in array order, return true, short-circuiting the execution of the rest.

some, its inverse every (which will stop on a return false), and forEach are all ECMAScript Fifth Edition methods which will need to be added to the Array.prototype on browsers where they're missing.

2016/09/09
2216
9/9/2016 9:01:04 PM

There is now an even better way to do this in ECMAScript2015 (aka ES6) using the new for of loop. For example, this code does not print the array elements after the number 5:

let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let el of arr) {
  console.log(el);
  if (el === 5) {
    break;
  }
}

From the docs:

Both for...in and for...of statements iterate over something. The main difference between them is in what they iterate over. The for...in statement iterates over the enumerable properties of an object, in original insertion order. The for...of statement iterates over data that iterable object defines to be iterated over.

Need the index in the iteration? You can use Array.entries():

for (const [index, el] of arr.entries()) {
  if ( index === 5 ) break;
}
2018/05/15

You can use every method:

[1,2,3].every(function(el) {
    return !(el === 1);
});

ES6

[1,2,3].every( el => el !== 1 )

for old browser support use:

if (!Array.prototype.every)
{
  Array.prototype.every = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this &&
          !fun.call(thisp, this[i], i, this))
        return false;
    }

    return true;
  };
}

more details here.


Quoting from the MDN documentation of Array.prototype.forEach():

There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behaviour, the .forEach() method is the wrong tool, use a plain loop instead. If you are testing the array elements for a predicate and need a boolean return value, you can use every() or some() instead.

For your code (in the question), as suggested by @bobince, use Array.prototype.some() instead. It suits very well to your usecase.

Array.prototype.some() executes the callback function once for each element present in the array until it finds one where callback returns a truthy value (a value that becomes true when converted to a Boolean). If such an element is found, some() immediately returns true. Otherwise, some() returns false. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.

2018/05/02

Unfortunately in this case it will be much better if you don't use forEach. Instead use a regular for loop and it will now work exactly as you would expect.

var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
  if (array[i] === 1){
    break;
  }
}
2017/12/07

From your code example, it looks like Array.prototype.find is what you are looking for: Array.prototype.find() and Array.prototype.findIndex()

[1, 2, 3].find(function(el) {
    return el === 2;
}); // returns 2
2017/04/04

Source: https://stackoverflow.com/questions/2641347
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]