Why filter method can't work with ternary conditional as it works with if conditionals ?
In case it works with if..else
let numbers = [-1, -2, -3, 1, 2, 3];
let negatives = [];
let positives = numbers.filter(num => {
if(num > 0) {
return num; // positives array => [1, 2, 3]
} else {
negatives.push(num); // negatives array => [-1, -2, -3]
}
})
In case it works with ?
let positives = numbers.filter(num => num > 0 ? num : negatives.push(num));
// positives array => [-1, -2, -3, 1, 2, 3]
// negatives array => [-1, -2, -3]
I tried filter method with if conditionals and it returns the result as I expect. but what is not expected for me the result when it works with ternary conditional.
CodePudding user response:
The issue is that you are misunderstanding what the code you pasted does.
Let's see.. in the first code, the fitering function returns either num
or nothing (after negatives.push()
there is no return
, so it implicitly returns undefined
).
function fn(){
// no explicit return
}
const what = fn();
typeof what === "undefined"; // true
The second version, returns either num
or the returned value of negatives.push()
call, which is by definition:
Return value
The new length property of the object upon which the method was called.
So in the second version of the code, the filter
receives for every negative number: 0, 1, 2... and so on. The first occurrence will be taken as a "falsy" (0 is a "falsy" value in JS) so it will be filtered out from the resulting array, the following negative numbers will be included in the resulting array as the filtering function will return "truthy" values for them (positive numbers are "truthy" values in JS)
Being that said...
It is a bad practice to use a filter
function for other task than filtering things.
In this scenario where you need to separate positives from negatives, use forEach
which is more clear and appropriate.
const positives = [];
const negatives = [];
numbers.forEach(num => {
if(num > 0) { // Note: that this comparison will send ZEROES to negatives array, which could lead to a bug.
positives.push(num);
} else {
negatives.push(num);
}
});
or simpler:
const positives = [];
const negatives = [];
numbers.forEach(num => (num > 0 ? positives : negatives).push(num));
CodePudding user response:
The array method filter
expects a callback which returns a boolean value. In your second example you are returning num
when num
is positive (which is truthy).
However, when num
is negative, the method returns the result of negatives.push(num)
which is also truthy.
CodePudding user response:
the filter
method is not returning a correct boolean value. It is better to return exact boolean 'type' value.
let numbers = [-1, -2, -3, 1, 2, 3];
const negatives = [];
const positives = numbers.filter((num) => {
if (num > 0) {
return true;
}
negatives.push(num);
return false;
});
console.log(negatives)
console.log(positives)