2148
[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.

Krisztián Balla
  • 19,223
  • 13
  • 68
  • 84
Scott Klarenbach
  • 37,171
  • 15
  • 62
  • 91
  • 27
    It is worth noting that while `return` does indeed continue the iteration, it will skip any code that comes after it in the block. Take this code for instance: ```[1,2,3].forEach(function(el) { if(el === 2) { console.log(`Match on 2!`); return; } console.log(el); });``` .The `console.log(el);` will be skipped when 2 is matched. – Shanerk Aug 02 '19 at 16:31

31 Answers31

2811

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.

Use Array#every

[1, 2, 3].every(v => {
  if (v > 2) {
    return false // "break"
  }
  console.log(v);
  return true // must return true if doesn't break
});
João Pimentel Ferreira
  • 14,289
  • 10
  • 80
  • 109
bobince
  • 528,062
  • 107
  • 651
  • 834
  • 2
    As many above have said, this is a technically interesting hack, but since it subverts and confuses the intended meaning of `some`/`every`, it is very much a hack. Considered harmful. Using an old-school `for` and/or prefiltering/slicing your array aren't as sexy, but they're better ideas. – Kevin Nov 19 '15 at 00:20
  • 6
    You can also try to use ECMAScript2015 new for...of (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) which would do exactly what you are looking for but the drawback is that this solution can cause issues for older browsers. If you are looking for more generic solution that support more than just array, you could look at solution like this (https://github.com/nbouvrette/forEach) one who can solve all your problems if you are willing to go this route. – Nicolas Bouvrette Jun 12 '16 at 23:47
  • when using es6, `for of` might be the best choice, especially if not dealing with arrays. check the other answer below. – cregox Apr 16 '17 at 11:09
  • 17
    The use of `Array#some` is really nice. Firstly its compatible with most browsers including ie9 and firefox 1.5 also works really well. My example use case will be to find the index in an array of ranges[a,b] where a number is between a lower boundary and upper boundary pair, test and return true when found. `for..of` would be the next best solution though only for newer browsers. – Sojimaxi Nov 02 '17 at 16:08
  • 247
    Exception handling should NEVER be used as control flow. PERIOD. – frank Nov 10 '17 at 23:00
  • 11
    @frank I [wrote an esolang with only one loop construct: `forever`](https://gist.github.com/amcgregor/a816599dc9df860f75bd?ts=4#file-sample-clu-L67-L99). All other loop constructs are formed from `forever` and appropriate iterable exceptions, such as `ContinueIteration` and `StopIteration` (which `break` is a macro to raise). On one hand: never. On the other hand: always. On the gripping hand: __sometimes__? The "PERIOD" in your comment implies there may be a citation to back up your suggestion? – amcgregor Oct 31 '18 at 18:03
  • 8
    @frank it depends on the language. In Python it is perfectly acceptable to control flow with exception handling. In fact, `__next__()` raises `StopIteration` after generator exhaustion for that reason, as it is generally the best way to detect the end of a generator - it's way better than relying on magic return values. Python's ducktyping and EAFP patterns generally depend on exception handling as a flow control mechanic. – cowbert Nov 08 '18 at 02:51
  • 1
    Using exception handling as control flow is bad juju. Use exceptions to notify of exceptions and handle them as unexpected results. They are not conditional operators. – Antony Booth Jan 11 '19 at 16:27
  • 2
    This is a (very) old answer and flings bad practises (one simply does not use exceptions here). Keep scrolling down for better suggestions. – Coreus Apr 09 '19 at 16:34
  • 2
    Upvoted for the use of "some". I would consider the exception version "bad practice" since it would be throwing an exception for a "normal" condition, thereby irritating those of us who like to debug with "halt on handled exceptions" turned on. – Steve In CO Dec 12 '19 at 23:42
  • 2
    Yes, exception handling should not be used as a control flow ... except that `try-catch` is a construct that is *intended* to be used with more than just exception. The only problem there is then the `BreakException` name. JS's try/catch comes from a Lisp legacy, and the [WP page on it](https://en.wikipedia.org/wiki/Exception_handling#History) even says: "This was rapidly used not only for error raising, but **for non-local control flow**, and thus was augmented by two new keywords, `CATCH` and `THROW`" – Eli Barzilay Jun 17 '20 at 01:10
  • 1
    I wouldn't use "some" since it was not the intention of the code (bad readability). – Cesar Feb 28 '21 at 11:21
  • How is this an accepted solution!? Do NOT use exceptions as control flow! – Jiri Kralovec Oct 24 '22 at 07:01
  • @KarlAdler It probably depends on the task, but I'm leaning towards some/every being a hack in this case. Less readable because it's generally used for different purposes. find() might be a bit more readable. But generally it's best to find the element(s) and do with them what you need (after that). – x-yuri Mar 29 '23 at 14:42
825

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:

const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (const 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;
}
canac
  • 15,440
  • 2
  • 16
  • 11
  • 8
    @superhero You can get the index of the element in a for...of loop, you just have to use `entries`. for (const [index, element] of someArray.entries()) { // ... } – blackxored Jan 19 '18 at 13:19
  • 1
    isn't it recommended not to use for...in with arrays ? – shehata Jun 20 '18 at 15:19
  • 7
    @emostafa You are correct about for _in_ loops not being recommended for arrays, but this is approach actually uses a for **of** loop. – canac Jun 21 '18 at 17:33
  • 1
    This is "for of", and this is a really clean solution... but this is also an ES6 feature, so just be aware that this will only work if your environment is setup for ES6. – Chad Jul 16 '19 at 18:10
  • 1
    I find myself using this solution a lot, and I use it for objects as well. With objects, you can do `Object.entries(myObject)` and then use it exactly like you use the `for..in` for the array. Note that JS arrays are basically objects under the hood: http://blog.niftysnippets.org/2011/01/myth-of-arrays.html – Andrew Oct 25 '19 at 17:44
  • How exactly does it answer the question? – Salman A May 27 '23 at 17:37
  • A simple for loop is still faster than the _better_ way. – Salman A Jun 05 '23 at 19:12
240

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.

Valdemar_Rudolfovich
  • 3,021
  • 2
  • 18
  • 17
  • 12
    Nice and clean in ES6 now - `[1,2,3].every( el => el !== 1 )` – metame Jan 04 '17 at 05:11
  • 1
    @Valdemar, But does `every` **guarantee** that calls are made in sequence? – Pacerier Apr 02 '17 at 09:25
  • 4
    @Pacerier, you can see the algorithm in the ES6 specification that the index `k` starts at 0 and is incremented by 1: [http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.every](http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.every) – XP1 Jun 26 '17 at 00:51
  • @XP1, Are all implementors required to do it that way? – Pacerier Aug 07 '17 at 01:22
  • 1
    @Pacerier, yes, most popular implementations work properly. If you are concerned about embedded implementations, usually it's Opera or webkit. Method every calls callbackfn once for each element present in the array, **in ascending order**, until it finds one where callbackfn returns false. Also look at step 7. Let k be 0. and 8.e Increase k by 1. – Valdemar_Rudolfovich Aug 08 '17 at 06:39
  • 1
    Changes the intention of the code. Very bad. – Cesar Feb 28 '21 at 11:23
  • @Cesar, thanks for replying, but could you please explain, why does it change intention? I thought the intention was to do something and exit forEach cycle in some moment. – Valdemar_Rudolfovich Mar 01 '21 at 16:01
  • 1
    @Valdemar_Rudolfovich the usage of "some" is finding if some items match some criteria, "every" is intended to find out if all the items in a set match a criteria. On the other hand breaking isn't always connected to a criteria but breaks some logic. Although the example given (if(el === 1)) might be implemented by "some", but I believe the question was about a general case. – Cesar Mar 02 '21 at 17:16
  • @Cesar, thanks again for the explanation, I agree with you, that the "some" method might be better in a particular case when you are searching for one exact condition. But if you are inverting the condition or say that I want to check that none of the elements equals 1, then the "every" method might be used as well. The question was about breaking the loop, both of these methods are suitable there. – Valdemar_Rudolfovich Mar 03 '21 at 18:47
  • 1
    MDN also has a polyfill: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every#polyfill – thdoan May 18 '21 at 23:12
138

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.

Rahul Desai
  • 15,242
  • 19
  • 83
  • 138
116

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;
  }
}
Weston Ganger
  • 6,324
  • 4
  • 41
  • 39
  • 62
    It shocks me that the highest vote is the worst implementation possible, compared to the higher performing, less code, and better readability of this correct answer. Throw exception... really? Is the traditional for loop just not kewl enough? – gdbj Oct 20 '17 at 21:07
  • 3
    @gdbj I agree with your statement and used this method, but what really shocks me is there is no way of exiting a forEach without these hacks, now that's bad design. – ScottN Aug 03 '18 at 18:11
  • 2
    @gdbj I also agree, but the issue is more with Stack Overflow and its guidelines. The question specifically asks for a solution to break out of an Array.forEach loop. The accepted answer does that... in an incredibly ugly way. Technically this answer is incorrect, even though it achieves the same goal in a tried and true fashion. – Nick M Sep 04 '20 at 23:18
42

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
Mahdi
  • 9,247
  • 9
  • 53
  • 74
Oliver Moran
  • 5,137
  • 4
  • 31
  • 45
29

Consider to use jquery's each method, since it allows to return false inside callback function:

$.each([{user: "barney", active: false}, {user: "fred", active: false}],function(e, i) { 
   if (i % 2) return false;
   console.log(e)
})

Lodash libraries also provides takeWhile method that can be chained with map/reduce/fold etc:

var users = [
  { 'user': 'barney',  'active': false },
  { 'user': 'fred',    'active': false },
  { 'user': 'pebbles', 'active': true }
];
 
_.takeWhile(users, function(o) { return !o.active; });
// => objects for ['barney', 'fred']
 
// The `_.matches` iteratee shorthand.
_.takeWhile(users, { 'user': 'barney', 'active': false });
// => objects for ['barney']
 
// The `_.matchesProperty` iteratee shorthand.
_.takeWhile(users, ['active', false]);
// => objects for ['barney', 'fred']
 
// The `_.property` iteratee shorthand.
_.takeWhile(users, 'active');
// => []
Jacques
  • 991
  • 1
  • 12
  • 15
vittore
  • 17,449
  • 6
  • 44
  • 82
  • 1
    Good reason to use jQuery. forEach in native javascript is still lacking. – Alex Grande Feb 11 '12 at 08:46
  • 3
    @AlexGrande jQuery's forEach and JavaScript's forEach are not compatible. – Bjorn Apr 22 '13 at 12:56
  • 13
    JavaScript is used in many places that jQuery is not an option. – JBRWilkinson May 09 '16 at 08:45
  • The jQuery code using `each` is incorrect. It takes an array and a callback. It should rather be something like: `$.each(array,function(e, i) { if (i % 2) return false; console.log(e) });` See: [jQuery documentation](https://api.jquery.com/jQuery.each/#jQuery-each-array-callback) – Jacques Feb 11 '23 at 20:04
21

If you would like to use Dean Edward's suggestion and throw the StopIteration error to break out of the loop without having to catch the error, you can use the following the function (originally from here):

// Use a closure to prevent the global namespace from be polluted.
(function() {
  // Define StopIteration as part of the global scope if it
  // isn't already defined.
  if(typeof StopIteration == "undefined") {
    StopIteration = new Error("StopIteration");
  }

  // The original version of Array.prototype.forEach.
  var oldForEach = Array.prototype.forEach;

  // If forEach actually exists, define forEach so you can
  // break out of it by throwing StopIteration.  Allow
  // other errors will be thrown as normal.
  if(oldForEach) {
    Array.prototype.forEach = function() {
      try {
        oldForEach.apply(this, [].slice.call(arguments, 0));
      }
      catch(e) {
        if(e !== StopIteration) {
          throw e;
        }
      }
    };
  }
})();

The above code will give you the ability to run code such as the following without having to do your own try-catch clauses:

// Show the contents until you get to "2".
[0,1,2,3,4].forEach(function(val) {
  if(val == 2)
    throw StopIteration;
  alert(val);
});

One important thing to remember is that this will only update the Array.prototype.forEach function if it already exists. If it doesn't exist already, it will not modify the it.

Chris West
  • 885
  • 8
  • 17
18

Short answer: use for...break for this or change your code to avoid breaking of forEach. Do not use .some() or .every() to emulate for...break. Rewrite your code to avoid for...break loop, or use for...break. Every time you use these methods as for...break alternative God kills kitten.

Long answer:

.some() and .every() both return boolean value, .some() returns true if there any element for which passed function returns true, every returns false if there any element for which passed function returns false. This is what that functions mean. Using functions for what they doesn't mean is much worse then using tables for layout instead of CSS, because it frustrates everybody who reads your code.

Also, the only possible way to use these methods as for...break alternative is to make side-effects (change some vars outside of .some() callback function), and this is not much different from for...break.

So, using .some() or .every() as for...break loop alternative isn't free of side effects, this isn't much cleaner then for...break, this is frustrating, so this isn't better.

You can always rewrite your code so that there will be no need in for...break. You can filter array using .filter(), you can split array using .slice() and so on, then use .forEach() or .map() for that part of array.

Max
  • 623
  • 6
  • 8
  • using .filter is actually the appropriate solution for a lot of use cases for breaking. – TKoL Jun 08 '15 at 17:49
  • What about performance? Woudln't filter affect performance if used frequently? – tfrascaroli May 25 '16 at 13:19
  • Yes, the filter array prototype can get heavy. I love it, but it could effect performance if it's overused. – Chad Jul 16 '19 at 18:17
  • @tfrascaroli use `for...break` loop if you need performance. `for` loop is the most performant iteration tool than `.forEach()`, `.any()`, `.map()`, `.filter()` etc. – Max Jul 17 '19 at 01:53
  • Why is using a table for layout a bad thing if you intend to build a table? Actually, not using a table when needing a table is just like using some, every instead of breaking. The table thing has nothing to do with readability. – Cesar Feb 28 '21 at 11:26
11

As mentioned before, you can't break .forEach().

Here's a slightly more modern way of doing a foreach with ES6 Iterators. Allows you to get direct access to index/value when iterating.

const array = ['one', 'two', 'three'];

for (const [index, val] of array.entries()) {
  console.log('item:', { index, val });
  if (index === 1) {
    console.log('break!');
    break;
  }
}

Output:

item: { index: 0, val: 'one' }
item: { index: 1, val: 'two' }
break!

Links

Alex
  • 1,689
  • 18
  • 27
8

Another concept I came up with:

function forEach(array, cb) {
  var shouldBreak;
  function _break() { shouldBreak = true; }
  for (var i = 0, bound = array.length; i < bound; ++i) {
    if (shouldBreak) { break; }
    cb(array[i], i, array, _break);
  }
}

// Usage

forEach(['a','b','c','d','e','f'], function (char, i, array, _break) {
  console.log(i, char);
  if (i === 2) { _break(); }
});
c24w
  • 7,421
  • 7
  • 39
  • 47
  • The syntax is similar to [NSArray enumerateObjectsUsingBlock], Thanks! – Chrstpsln May 10 '19 at 15:23
  • @Drenai the signature is analogous to the native [`Array.prototype.forEach()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach). [`for`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for) and [`break`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break) existed long before this question was asked; the OP was looking for that behaviour using, the more functional, `forEach`. – c24w Oct 23 '19 at 10:15
  • @Drenai has now deleted their comment (but left the downvote) which mentioned that the signature of this solution is hard to remember and unnecessary when you can solve the problem with `for...in` and `break`. – c24w Oct 25 '19 at 09:32
7

This is just something I came up with to solve the problem... I'm pretty sure it fixes the problem that the original asker had:

Array.prototype.each = function(callback){
    if(!callback) return false;
    for(var i=0; i<this.length; i++){
        if(callback(this[i], i) == false) break;
    }
};

And then you would call it by using:

var myarray = [1,2,3];
myarray.each(function(item, index){
    // do something with the item
    // if(item != somecondition) return false; 
});

Returning false inside the callback function will cause a break. Let me know if that doesn't actually work.

tennisgent
  • 79
  • 1
  • 1
  • 2
    `=== false` might be better than `== false` so you don't have to explicitly return true (or a truthy value) to continue the loop, lest some control path doesn't return a value and the loop breaks unexpectedly. – Jake Apr 27 '17 at 23:03
6

If you don't need to access your array after iteration you can bail out by setting the array's length to 0. If you do still need it after your iteration you could clone it using slice..

[1,3,4,5,6,7,8,244,3,5,2].forEach(function (item, index, arr) {
  if (index === 3) arr.length = 0;
});

Or with a clone:

var x = [1,3,4,5,6,7,8,244,3,5,2];

x.slice().forEach(function (item, index, arr) {
  if (index === 3) arr.length = 0;
});

Which is a far better solution then throwing random errors in your code.

3rdEden
  • 4,388
  • 1
  • 20
  • 18
  • well done :) but if there are some actions after assigning `array.length` to `0` they will apply in current iteration, so probably it's sometimes better to use `return` after such assigning – zhibirc Jul 19 '18 at 13:09
4

Found this solution on another site. You can wrap the forEach in a try / catch scenario.

if(typeof StopIteration == "undefined") {
 StopIteration = new Error("StopIteration");
}

try {
  [1,2,3].forEach(function(el){
    alert(el);
    if(el === 1) throw StopIteration;
  });
} catch(error) { if(error != StopIteration) throw error; }

More details here: http://dean.edwards.name/weblog/2006/07/enum/

RussellUresti
  • 6,211
  • 4
  • 28
  • 26
  • 7
    Don't use exceptions as a control flow statements. Use it for handling unexpected results. – Max Jul 17 '19 at 01:54
4

This is a for loop, but maintains the object reference in the loop just like a forEach() but you can break out.

var arr = [1,2,3];
for (var i = 0, el; el = arr[i]; i++) {
    if(el === 1) break;
}
jamos
  • 213
  • 2
  • 8
2

try with "find" :

var myCategories = [
 {category: "start", name: "Start", color: "#AC193D"},
 {category: "action", name: "Action", color: "#8C0095"},
 {category: "exit", name: "Exit", color: "#008A00"}
];

function findCategory(category) {
  return myCategories.find(function(element) {
    return element.category === category;
  });
}

console.log(findCategory("start"));
// output: { category: "start", name: "Start", color: "#AC193D" }
Gigoland
  • 1,287
  • 13
  • 10
2

Yet another approach:

var wageType = types.filter(function(element){
  if(e.params.data.text == element.name){
    return element;
  }
});
console.dir(wageType);
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
Harry Bosh
  • 3,611
  • 2
  • 36
  • 34
  • Is this right usage of filter method? I guess callback returns a boolean that regardless of it, callback is called array elements until the last one. – MortezaE Jun 07 '20 at 07:22
  • The question says "short circuit", filter does not. – Salman A May 27 '23 at 18:07
1

I use nullhack for that purpose, it tries to access property of null, which is an error:

try {
  [1,2,3,4,5]
  .forEach(
    function ( val, idx, arr ) {
      if ( val == 3 ) null.NULLBREAK;
    }
  );
} catch (e) {
  // e <=> TypeError: null has no properties
}
//
public override
  • 974
  • 8
  • 17
0

Use the array.prototype.every function, which provide you the utility to break the looping. See example here Javascript documentation on Mozilla developer network

Yiling
  • 2,817
  • 2
  • 21
  • 27
0

Agree with @bobince, upvoted.

Also, FYI:

Prototype.js has something for this purpose:

<script type="text/javascript">
  $$('a').each(function(el, idx) {
    if ( /* break condition */ ) throw $break;
    // do something
  });
</script>

$break will be catched and handled by Prototype.js internally, breaking the "each" cycle but not generating external errors.

See Prototype.JS API for details.

jQuery also has a way, just return false in the handler to break the loop early:

<script type="text/javascript">
  jQuery('a').each( function(idx) {
    if ( /* break condition */ ) return false;
    // do something

  });
</script>

See jQuery API for details.

Dmitri Sologoubenko
  • 2,909
  • 1
  • 23
  • 27
0

If you want to keep your forEach syntax, this is a way to keep it efficient (although not as good as a regular for loop). Check immediately for a variable that knows if you want to break out of the loop.

This example uses a anonymous function for creating a function scope around the forEach which you need to store the done information.

(function(){
    var element = document.getElementById('printed-result');
    var done = false;
    [1,2,3,4].forEach(function(item){
        if(done){ return; }
        var text = document.createTextNode(item);
        element.appendChild(text);
        if (item === 2){
          done = true;
          return;
        }
    });
})();
<div id="printed-result"></div>

My two cents.

Justus Romijn
  • 15,699
  • 5
  • 51
  • 63
0

If you need to break based on the value of elements that are already in your array as in your case (i.e. if break condition does not depend on run-time variable that may change after array is assigned its element values) you could also use combination of slice() and indexOf() as follows.

If you need to break when forEach reaches 'Apple' you can use

var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var fruitsToLoop = fruits.slice(0, fruits.indexOf("Apple"));
// fruitsToLoop = Banana,Orange,Lemon

fruitsToLoop.forEach(function(el) {
    // no need to break
});

As stated in W3Schools.com the slice() method returns the selected elements in an array, as a new array object. The original array will not be changed.

See it in JSFiddle

Hope it helps someone.

Ula
  • 2,628
  • 2
  • 24
  • 33
0

Why don't you try wrapping the function in a Promise?

The only reason I bring it up is that I am using a function in an API that acts in a similar manner to forEach. I don't want it to keep iterating once it finds a value, and I need to return something so I am simply going to resolve a Promise and do it that way.

traverseTree(doc): Promise<any> {
  return new Promise<any>((resolve, reject) => {
    this.gridOptions.api.forEachNode((node, index) => {
    //the above function is the one I want to short circuit.
      if(node.data.id === doc.id) {
        return resolve(node);
      }
    });
  });
}

Then all you need to do is do something with the result like

this.traverseTree(doc).then((result) => {
   this.doSomething(result);
});

My above example is in typescript, simply ignore the types. The logic should hopefully help you "break" out of your loop.

Willie
  • 281
  • 3
  • 21
-1

This isn't the most efficient, since you still cycle all the elements, but I thought it might be worth considering the very simple:

let keepGoing = true;
things.forEach( (thing) => {
  if (noMore) keepGoing = false;
  if (keepGoing) {
     // do things with thing
  }
});
martyman
  • 867
  • 8
  • 14
-1

you can follow the code below which works for me:

 var     loopStop = false;
YOUR_ARRAY.forEach(function loop(){
    if(loopStop){ return; }
    if(condition){ loopStop = true; }
});
Ian Clark
  • 9,237
  • 4
  • 32
  • 49
BERGUIGA Mohamed Amine
  • 6,094
  • 3
  • 40
  • 38
-1

Breaking out of built-in Array.prototype.map function esp in React

The key thing to note here is the use of statement return to BREAK

let isBroken = false;

colours.map(item => {
    if (isBroken) {
        return;
    }
    if (item.startsWith("y")) {
        console.log("The yessiest colour!");
        isBroken = true;
        return;
    }
});

More information here: https://www.codegrepper.com/code-examples/javascript/break+out+of+map+javascript

Ngatia Frankline
  • 2,897
  • 2
  • 20
  • 19
-2

I know it not right way. It is not break the loop. It is a Jugad

let result = true;
[1, 2, 3].forEach(function(el) {
    if(result){
      console.log(el);
      if (el === 2){
        result = false;
      }
    }
});
Durgpal Singh
  • 11,481
  • 4
  • 37
  • 49
-2

You can create a variant of forEach that allows for break, continue, return, and even async/await: (example written in TypeScript)

export type LoopControlOp = "break" | "continue" | ["return", any];
export type LoopFunc<T> = (value: T, index: number, array: T[])=>LoopControlOp;

Array.prototype.ForEach = function ForEach<T>(this: T[], func: LoopFunc<T>) {
    for (let i = 0; i < this.length; i++) {
        const controlOp = func(this[i], i, this);
        if (controlOp == "break") break;
        if (controlOp == "continue") continue;
        if (controlOp instanceof Array) return controlOp[1];
    }
};

// this variant lets you use async/await in the loop-func, with the loop "awaiting" for each entry
Array.prototype.ForEachAsync = async function ForEachAsync<T>(this: T[], func: LoopFunc<T>) {
    for (let i = 0; i < this.length; i++) {
        const controlOp = await func(this[i], i, this);
        if (controlOp == "break") break;
        if (controlOp == "continue") continue;
        if (controlOp instanceof Array) return controlOp[1];
    }
};

Usage:

function GetCoffee() {
    const cancelReason = peopleOnStreet.ForEach((person, index)=> {
        if (index == 0) return "continue";
        if (person.type == "friend") return "break";
        if (person.type == "boss") return ["return", "nevermind"];
    });
    if (cancelReason) console.log("Coffee canceled because: " + cancelReason);
}
Venryx
  • 15,624
  • 10
  • 70
  • 96
  • This would require anyone to get back and read the Array prototype which seems not trivial and a waste of time – Gal Bracha Feb 02 '21 at 13:41
  • No, the "continue", "break", and "return" strings/operators are processed within the `ForEach` function (it's _not_ the generic `forEach` function) -- the caller does not need to read anything on the Array prototype. That said, I don't actually use the solution above in production code -- it's just showing how one could accomplish those various operators within a `forEach`-like function, if they wished to. – Venryx Feb 02 '21 at 16:03
  • Yes. And still - if I would encounter this - it would not be clear at first look. – Gal Bracha Feb 02 '21 at 16:53
-2

In fact, I don't understand the reward for this old question. But if you really want to interrupt the foreach cycle, using only the foreach cycle, you can use the second parameter of the method to save the original array after its zeroing. Something like this:

let array = [1, 2, 3];
array.forEach(function(el) {
    console.log(el);
    if(el === 1) {
        array = [...this];
        this.length = 0;
    }
}, array);
console.log(array);

P.S. I am in no way not advise that this should be done. On the contrary, I advise you to bypass my answer and use the previous best suggestions. Best regards.

imhvost
  • 4,750
  • 2
  • 8
  • 10
-5

I use return false and it works for me.

Robby Lebotha
  • 1,211
  • 11
  • 9
-6
const Book = {"Titles":[                          
    {"Book3" : "BULLETIN 3"},
    {"Book1" : "BULLETIN 1"},
    {"Book2" : "BULLETIN 2"}    
]}

const findbystr = function(str) { 
    Book.Titles.forEach(function(data) { 
        if (typeof data[str] != 'undefined') {
            return data[str];
        } 
    }, str) 
}

book = findbystr('Book1');

console.log(book);
Neoheurist
  • 3,183
  • 6
  • 37
  • 55
Samuel Gray
  • 119
  • 1
  • 5
  • I like this approach (I've edited the code so that the value is immediately returned from the function when found) - if you were to write up how the return within the forEach has the effect of a break statement you'd probably accrue some up votes for this option. – Neoheurist Mar 08 '21 at 22:39