0

As practice, I want to write a function all() that works similar to the Array.prototype.every() method. This function returns true only if the predicate supplied returns true for all the items in the array.

Array.prototype.all = function (p) {
  this.forEach(function (elem) {
    if (!p(elem)) 
      return false;
  });
  return true;
};

function isGreaterThanZero (num) {
  return num > 0;
}

console.log([-1, 0, 2].all(isGreaterThanZero)); // should return false because -1 and 0 are not greater than 0

Somehow this doesn't work and returns true. What's wrong with my code? Is there a better way to write this?

3
  • Possible duplicate of What does `return` keyword mean inside `forEach` function? Commented Jul 25, 2017 at 17:37
  • 1
    You might find this link interesting reactivex.io/learnrx And take a look at libraries like lodash lodash.com/docs/4.17.4 Commented Jul 25, 2017 at 17:42
  • If you look at your console, you'll see that you get nothing for -1, true for 0, and true for 2. You're not killing the loop when it returns false. You can't kill the loop with a forEach because it's specifically for running through each item. Commented Jul 25, 2017 at 17:43

4 Answers 4

2

You can't break out of an Array#forEach loop by returning. Use a for loop instead.

Note: This is a partial implementation of Array#every to demonstrate the return issue.

Array.prototype.all = function (p) {
  for(var i = 0; i < this.length; i++) {
    if(!p(this[i])) {
      return false;
    }
  }
  
  return true;
};

function isGreaterThanZero (num) {
  return num > 0;
}

console.log([-1, 0, 2].all(isGreaterThanZero)); 

Sign up to request clarification or add additional context in comments.

Comments

0

return in foreach function is not returning value from your function. You can code like this.

        Array.prototype.all = function (p) {
            for(var i = 0; i < this.length; i++){
                if (!p(this[i])) 
                    return false;
            }                
            return true;
        };

        function isGreaterThanZero (num) {
            return num > 0;
        }

        var result = [2, 3, 4].all(isGreaterThanZero);
        console.log("result", result);

Comments

0

The other answers are slightly wrong. The callback you pass in should be called with 3 arguments: the current item, the index, and the entire array. This is how the native Array.every, and indeed most native array functions, work. Your callback can choose to use these arguments but most of the time it doesn't.

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

  return true;
};

function isGreaterThanZero (num) {
  return num > 0;
}

console.log([-1, 0, 2].all(isGreaterThanZero)); // should return false because -1 and 0 are not greater than 0

1 Comment

If you're going for the full Array#every implementation, don't forget to add the thisArg.
0

You can only stop a forEach() loop by throwing an exception. Just use a normal for loop instead.

Array.prototype.all = function (p) {
  for(var i = 0; i < this.length; i++) {
    if(!p(this[i])) {
      return false;
    }
  }
  return true;
};

If any method other than Array.prototype.every() is allowed to be used, then you can:

Array.prototype.all = function (p) {
  return this.filter(p).length == this.length;
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.