0

Note: I want to break the while() loop using the forEach callback function, not to break the forEach itself.

I'm currently trying to break a while loop in a forEach method inside that same while loop, but Javascript does not like break statements inside functions. It spits out unsynctatic break or illegal break statement depending on the environment.

I'm trying to do something like this:

while(true) {
    example = [false, false, true];
    example.forEach(function breakWhile(element) {
        if(element) {break;}
    })
}

I'm aware that for...of (plus using a label on the while loop) solves this, but is it really my only way out? I quite prefer using array.forEach. And even worse, I could want to use a function instead, which is also underappreciated by JS engines.

Rafael
  • 557
  • 6
  • 21
  • 3
    Possible duplicate of [How to short circuit Array.forEach like calling break?](https://stackoverflow.com/questions/2641347/how-to-short-circuit-array-foreach-like-calling-break) – Void Ray Sep 29 '17 at 14:51
  • @VoidRay not really, I want to break the while() loop, not the forEach. – Rafael Sep 29 '17 at 14:51
  • There are [`every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every) and [`some`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) that you should use here, along with several other [`Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Methods_2) methods. – Sebastian Simon Sep 29 '17 at 14:52
  • @Rafael then you'll have to break it like any other while loop. running break in a callback certainly isn't the same as running it in the while loop. Your options are limited here. Breaking the forEach would be the first step. – Kevin B Sep 29 '17 at 15:32

1 Answers1

3

I think your best option is just to use a flag.

let dobreak = false;
while(!dobreak) {
    example = [false, false, true, false];
    example.forEach(function breakWhile(element) {
        if(element) {dobreak = true;}
        else if(!dobreak) {
          console.log(element);
        }
    })
}

Another idea is to create a function to replace the built-in forEach, here I've called it breakForEach if you return true inside the iteration callback it will break the forEach, and also return true so you can break the while.

You could even add this to the default Array.prototype, but it's not advisable.

function breakForEach(arr, iter) {
  for(let l = 0; l < arr.length; l ++) {
    if (iter(arr[l])) return true;    
  }
  return false;
}

while(true) {
    var example = [false, false, true, false];
    if (breakForEach(example, function breakWhile(element) {
        if(element) return true;
        console.log(element);
    })) break;
}
Keith
  • 22,005
  • 2
  • 27
  • 44
  • Hmmm. That's not exactly what I wished (`break` is cleaner), but it is indeed a solution. Will wait a bit for a possible better solution before accepting this, but +1 for coming up with a solution at least. ;) – Rafael Sep 29 '17 at 15:09
  • Is this a pattern you get regularly? If so you could maybe create a helper function,. maybe called `whileForEachBreak` or something like that. – Keith Sep 29 '17 at 15:11
  • Actually that's the first time I had to do this. A helper function would be also less clean than just `break`ing with the forEach, but that doesn't seem to be a possibility. – Rafael Sep 29 '17 at 15:31