Reputation: 21
I am working through the problems in Eloquent Javascript Ch 5 on Higher Order Functions. I am stuck on the last problem, 'Every and then Some', which can be found at the bottom of the page (sorry, reputation not high enough for mulitple links). I initially completed the assignment easily with a for loop, but was interested in trying to use the 'forEach' function that was mentioned earlier in the program:
var every = function(array, callback) {
each(array, function(element) {
if(callback(element) === false) {
return false;
}
});
return true;
}
But my code never seems to hit the 'return false' within the if block. I fixed this using a separate variable as a switch :
var every = function(array, callback) {
var boolSwitch = true;
each(array, function(element) {
if(!(callback(element))) {
boolSwitch = false;
}
});
return boolSwitch;
}
But am curious as to why my initial code doesn't work? Here is a jsfiddle I've been messing around with.
Initial code (WHY DOESN'T THIS WORK???) : https://jsfiddle.net/g5eqzs1b/
Thanks!
Upvotes: 1
Views: 292
Reputation: 2339
One more reason is that your return false or return true is dependent on your last return value not every return value, which is not really good way of identifying.
http://jsfiddle.net/g5eqzs1b/1
var every = function(array, callback) {
forEache(array, function(element) {
console.log(element);
let x = callback(element);
console.log(x);
if(x === false) {
return false;
}
});
return true;
}
What you should be doing is putting all the falsy or truthy in a array and check if even one is a falsy then return false for every() and similarly for some() logic. Second option is when running every if you get an falsy then just return false and close the callback in case of isNaN.
You basically have nested callbacks thats creating the confusion of capture of booleans.
Upvotes: 0
Reputation: 92274
It's because you're returning false from the inner anonymous function. That does not cause the iteration to stop, it works like a continue
Using the separate variable makes it so that the return false statement applies to the every
function instead of the inner anonymous function passed to each
Upvotes: 2
Reputation: 1190
What's happening is in your first example you're returning inside of your condition, which is inside of a function. That means the return is returning for the function supplied to each
, not every
.
each(array, function(element) { // <-- This is a new function scope!
if(callback(element) === false) {
return false; // This returns for that new function scope, not the original one.
}
});
In your second example, you store the callback in a variable that you return from the original function's scope.
var every = function(array, callback) {
var boolSwitch = false;
each(array, function(element) {
if(!(callback(element))) {
boolSwitch = true;
}
});
return boolSwitch;
// This return references `every` since that's the function
// this return statement belongs to.
}
So your issue with the first example is that you were returning false to a function that did nothing with that false and didn't affect the output of every
.
Upvotes: 1
Reputation: 2612
You‘re not returning the result of each
. If you replace the anonymous function argument of the call to each
with a named function (to reduce clutter), it’s clear that the function will always return true
.
function f(element) { /* ... */ };
var every = function(array, callback) {
each(array, f);
return true;
}
Upvotes: 0