0

I'm attempting to create a function which accepts an array and a callback function. The function should return true if all values in the array passed to the callback return true, otherwise, return false. But I'm not sure what I'm doing incorrectly

const every = function(arr, callback) {
   arr.forEach(function(element) {     
     if(!callback(element)) {       
       return false         
     }       
   })      
   return true  
};  

every([1, 2, 3, 4, 5], function(val) {
    return val < 2
});

expected results => false but I'm getting true.

6
  • A return inside the callback to the forEach method does absolutely nothing in the function in which that method was called. I'd suggest filtering the array and testing the resulting length. Alternatively, newer versions of JavaScript actually have an every method on arrays: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Jan 4, 2019 at 23:37
  • 1
    Is it just me or is the callback being passed in malformed syntatically? The {} at the end of it looks strange Commented Jan 4, 2019 at 23:41
  • Array.prototype has an every that does what you want, e.g. [1, 2, 3, 4, 5].every(val => val < 2) Commented Jan 4, 2019 at 23:48
  • @ic3b3rg He's obviously trying to understand how to implement a similar function himself. Commented Jan 4, 2019 at 23:57
  • @Barmar Not so sure he's aware of Array.prototype.every Commented Jan 4, 2019 at 23:58

4 Answers 4

1

I would recommend using a simple for loop:

    const every = (arr, callback) => {
       for (let i = 0; i < arr.length; i++){
          if (callback(arr[i]) === false){
             return false;
       }
    }
       return true;
    };  

    console.log(every([1, 2, 3, 4, 5], function(val){return val < 2}));
Sign up to request clarification or add additional context in comments.

Comments

1

Returning false from the forEach callback will not also cause the every function to return. Instead it will simply continue the forEach iterator.

The most easy solution to your problem would be a for...of loop, since it allows you to use a return pattern similar to your snippet:

const every = function(arr, callback) {

  for (const element of arr) {
    if (!callback(element)) {
      return false;
    }
  }

  return true;
};

console.log(every([1, 2, 3, 4, 5], function(val) {
  return val < 2;
}));

Note: By using a loop construct every returns early. The forEach method of arrays always runs until all array elements are visited, but the loop breaks immediately after one element fails the test. A regular for loop would give you the same performance benefit.

1 Comment

This is good to know. I was wondering why the loop continues to iterate even after the condition was met. Thanks for this!
0

You could potentially use reduce() for this. If you base your reduction on the truth and the result of the callback, it will remain true so long as the callback is true. Once a callback is false, the check for truth in the conditional will short circuit the logic and the callback will not execute anymore. It will loop through all the elements though.

It also returns true for an empty array, which seems to match your original logics intent.

const every = function(arr, callback) {
  return arr.reduce(function(truth, element){
    return truth && callback(element);
  }, true);
};  

console.log(
  every([1, 2, 3, 4, 5], function(val){return val < 2})
);

console.log(
  every([], function(val){return val < 2})
);

1 Comment

Though as @ic3b3rg pointed out, Array.prototype.every exists, and appears to have close to the same browser support as Array.prototype.reduce
0
arr.forEach(function(element) {
    return false
})

Its the inner function returning false, which have no effect for the outer function (in this situation) you should create a new variable inside the outer function and instead of returning false in the inner function, change the variable at the end just return the variable

const every = function(arr, callback) {
    let isEvery = true
    arr.forEach(function(element) {     
        if(!callback(element)) { // or just isEvery = isEvery && statement
            isEvery = false
         }       
     })      
    return isEvery
};  

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.