Reputation: 125
I'm trying to figure out why, in my reducer function, can isTrue flip to true
from false
, but not back to false
when encountering a function that returns false . I'm just trying to understand why it can flip one way but not the other.
I know the flip happens in return isTrue || val(num);
Directions were "// define a function "passOne" which takes two arguments, the first is any value and the second is an array of functions. These functions can be considered tests, as they will all return either true or false. "passOne" will iterate/loop through the array and pass the value to each function as an argument. If at least one function(test) returns true, "passOne" will return true. If none of the functions return true, "passOne" will return false. // use your "passOne" to determine if the number 113 is negative, even, OR has 1 as the first digit. Then test 213."
i've tried visualizing it in Python Tutor.
function isNeg(num){
return num < 0 ? true: false;
}
function isEven(num){
return num % 2 === 0 ? true : false;
}
function oneDig(num){
return (num.toString())[0] === `1` ? true : false;
}
const funcs = [oneDig, isNeg, isEven];
// refactor "passOne" so that it uses the built-in "reduce" method instead of a "for" loop
function passOne(num, arr){
return arr.reduce((isTrue, val) => {
return isTrue || val(num);
}, false);
}
console.log(passOne(113, funcs)); //true
console.log(passOne(213, funcs)); //false
code is behaving as expected, I'm just not understanding why callbacks that return 'false' don't flip isTrue back to 'false', how does it stay 'true' and then not update to 'false', not that that's what the instructions say to do, i'm just curious.
Upvotes: 1
Views: 589
Reputation: 4867
I would use some
which tests whether at least one element in the array passes the test implemented by the provided function.
const isNeg = num => num < 0;
const isEven = num => num % 2 === 0;
const oneDig = num => (num.toString())[0] === `1`;
const passOne = (num, arr) => arr.some(fn => fn(num));
const funcs = [oneDig, isNeg, isEven];
console.log(passOne(113, funcs)); //true
console.log(passOne(213, funcs)); //false
Upvotes: 0
Reputation: 36584
It can never become false
again when isTrue
becomes true
.
Because you are using ||
operator. Consider isTrue
is true
. Then it doesn't matter what callback returns the whole value will will true
.
console.log(true || false)
You actually don't need reduce()
here because one of the condition is true you don't need to check further.You should use some()
in this case.
const passOne = (num, arr) => arr.some(x => x(num))
If you want to flip then it means you want the code to check for all the conditions. Then you need to use &&
operator. And pass true
instead of false
to reduce()
function isNeg(num){
return num < 0 ? true: false;
}
function isEven(num){
return num % 2 === 0 ? true : false;
}
function oneDig(num){
return (num.toString())[1] === `1` ? true : false;
}
const funcs = [oneDig, isNeg, isEven];
// refactor "passOne" so that it uses the built-in "reduce" method instead of a "for" loop
function passAll(num, arr){
return arr.reduce((isTrue, val) => {
return isTrue && val(num);
}, true);
}
console.log(passAll(113, funcs)); //false
console.log(passAll(213, funcs)); //false
console.log(passAll(-122, funcs)) //true
Or another way to do that is every()
const passOne = (num, arr) => arr.every(x => x(num))
Upvotes: 1
Reputation: 416
For 113,
accumulator is false
initialized.
So first time isTrue will be false. So it executes val(num)
.
Logical OR will go to next condition if its false, otherwise it wont go.
oneDig is the first item in the arr. oneDig checks for first digit of that number is 1.
so for 113, first digit is 1. So it returns true. After for other two val(num) is not executed since isTrue = true satisfies the LogicalOR.
For 213,
oneDig returns false. So it goes to val(num)
isNeg returns also false. So it goes again to val(num)
finally isEven also returns false.
So its like its like Array.prototype.some
to check any function in arr returns true, then finally it returns true else check for all functions and if nothing returns true, it will return false
Upvotes: 0
Reputation: 386700
You could take Array#some
instead of Array#reduce
and return the result of the callback.
const
isNeg = num => num < 0,
isEven = num => num % 2 === 0,
oneDig = num => num.toString()[0] === '1',
funcs = [oneDig, isNeg, isEven],
passOne = (num, arr) => arr.some(fn => fn(num));
console.log(passOne(113, funcs)); //true
console.log(passOne(213, funcs)); //false
Upvotes: 0