0

I have had a lot of trouble with JavaScript and 'break' statements coming from a Ruby background.

Here is my function:

function isItTheNumber(numberToGuess){

    if(previousGuess === null){
      previousGuess = [playersGuess];
    }

    previousGuess.forEach(function(guess){
      if(playersGuess === guess && previousGuess > 1){
        textStatus.style.display = 'block';
        textStatus.innerHTML = 'You already picked that number';
      } else if(parseInt(playersGuess) === parseInt(numberToGuess)){
        textStatus.style.display ='block';
        textStatus.innerHTML = 'You Are CORRECT!';    
      } else {
      previousGuess.push(playersGuess);
      textStatus.style.display='block';
      textStatus.innerHTML = 'You are ' + hotOrCold();
      document.getElementById('guess-count').innerHTML = playerGuessCount++;
    }
  });
}

In my .forEach loop I would like to have a 'break' statement in my first if statement. I would like the loop to stop if it ever executes this block.

I realize I can't use a break statement in this forEach function after reading a few posts about it. I attempted the suggestion here using "every" but when I was using this wrapped in a function I was not able to return a true or false value.

I would like to avoid having to use any type of 'break' or hack for the break but will use it if it is the only way. If anyone has any suggestions on how I can re-work my logic or have any suggestions I would appreciate it. I'll list my logic in pseudo code below.

1) Check if the previousGuess array is null or populated. If it is null, set it to an array with the first value.
2) Iterate over the previousGuess array.
3) If: see if the user input (playerGuess) is in the previousGuess array. The previous guess
array must be larger than 1.
4) Else If: If the users guess is the same as the a the value, tell them they are correct.
5) Else: if the users guess isn't the same as the value, tell them and add 1 to the playerGuessCount.

The problem with my current logic is that the playerGuessCount is being invoked too many times. If the array is being iterated over and finds and the first if statement is true, it will still iterate over the rest of the array, adding 1 to the playerGuessCount even when they only submit 1 guess. The .forEach is strictly there to check if their guess is a repeat.

Here is my attempt with 'every' http://repl.it/P74

Community
  • 1
  • 1
HelloWorld
  • 10,529
  • 10
  • 31
  • 50
  • 2
    Why doesn't `every` work? – salezica Mar 05 '14 at 02:37
  • JavaScript does not have a forEach function. It looks like you're using a framework that implements that function. Maybe try just returning false? – Femi Mar 05 '14 at 02:37
  • 6
    @MjrKusanagi [Array.prototype.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) – salezica Mar 05 '14 at 02:38
  • I'll try to work out the every again, when I was using it, I had it wrapped in another function and was using that function in an If statement. The problem I was having was that it wasn't returning true or false. When I took it out of the function I had it wrapped in, and it was in global space, it was working just fine but I can't keep it in global space. I'll try it again and add a repl.it link. Thanks! – HelloWorld Mar 05 '14 at 02:47
  • Can you post the code that didn't work with `every`? It should work just fine... – elclanrs Mar 05 '14 at 02:50

2 Answers2

3

The .forEach method you are using is a wrapper implemented by extending a function prototype.

You can break out of a conventional loop:

for (var key in objs){
  var obj=objs[key];
  //do your business here

  break; //this line exists the loop
}

However, if a callback function is used, you have to terminate the function call itself by placing a "skip" variable.

previousGuess.forEach(function(guess){
  if (this.skip_the_foreach_loop) return;
  if (need_to_exit) this.skip_the_foreach_loop=true;
});

Not the most efficient way but saves you a few CPU cycles.

Schien
  • 3,855
  • 1
  • 16
  • 29
0

Would this work for what you're trying to do?

function isItTheNumber(numberToGuess){

    if(previousGuess === null){
      previousGuess = [playersGuess];
    }

    // Using Array.prototype.every so a falsey return breaks
    previousGuess.every(function(guess){
      if(playersGuess === guess && previousGuess > 1){
        textStatus.style.display = 'block';
        textStatus.innerHTML = 'You already picked that number';
        return; // returns undefined which is falsey and breaks loop.
      } else if(parseInt(playersGuess) === parseInt(numberToGuess)){
        textStatus.style.display ='block';
        textStatus.innerHTML = 'You Are CORRECT!';    
      } else {
        previousGuess.push(playersGuess);
        textStatus.style.display='block';
        textStatus.innerHTML = 'You are ' + hotOrCold();
        document.getElementById('guess-count').innerHTML = playerGuessCount++;
      }
      return true; // Meaning go to next iteration
  });
}
Andrew Templeton
  • 1,656
  • 10
  • 13