Reputation: 11
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.
Upvotes: 0
Views: 125
Reputation: 7916
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.
Upvotes: 1
Reputation: 35
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}));
Upvotes: 1
Reputation: 537
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
};
Upvotes: 0
Reputation: 24965
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})
);
Upvotes: 0