I'm trying to avoid chaining with filter and map, but why my reduce returned undefined?
const data = [{
value: "moto",
passed: true
},{
value: "boat",
passed: false
}, {
value: "car",
passed: true
}]
// expected ['moto', 'car']
// using filter and map
data.filter(obj => obj.passed).map(obj => obj.value)
What's wrong?
data.reduce((accum, obj) => obj.checked && [...accum, obj.value], [])
I'm trying to avoid chaining with filter and map, but why my reduce returned undefined?
const data = [{
value: "moto",
passed: true
},{
value: "boat",
passed: false
}, {
value: "car",
passed: true
}]
// expected ['moto', 'car']
// using filter and map
data.filter(obj => obj.passed).map(obj => obj.value)
What's wrong?
data.reduce((accum, obj) => obj.checked && [...accum, obj.value], [])
- 1 It is "passed" not "checked" on your data. – Alex G Commented Nov 19, 2018 at 11:42
-
1
You need a ternary operator in your
reduce
callback, not&&
. Imagine what you return whenobj.passed
is false... it should beaccum
, but instead you returnfalse
. – trincot Commented Nov 19, 2018 at 11:43 -
2
What's wrong with chaining
filter
andmap
? – Denis Frezzato Commented Nov 19, 2018 at 11:44 - @Denis - you run similar loop 2 times instead of one. So it might, for example, take 4sec instead of 2sec. – pbialy Commented Nov 19, 2018 at 11:45
-
The solution with
reduce
would be this:data.reduce((accum, obj) => obj.passed ? [...accum, obj.value] : accum, [])
. But there is nothing wrong with usingfilter
andmap
. – Carsten Führmann Commented Nov 19, 2018 at 11:55
4 Answers
Reset to default 4You can do:
const data = [{value: "moto",passed: true}, {value: "boat",passed: false}, {value: "car",passed: true}];
const result = data.reduce((a, { passed: p, value: v}) => p ? (a.push(v), a) : a, []);
console.log(result);
(accum, obj) => obj.checked && [...accum, obj.value]
does not return the filtered list, in case the object is not checked.
(accum, obj) => {
if (obj.checked) accum.push(obj.value)
return accum;
}
as reducer function will do that.
or to keep it as a oneliner, to not maintain readability:
(accum, obj) => obj.checked ? [...accum, obj.value] : accum;
It's because you are not returning anything if obj.passed = false
. Updated below. Pls check
const data = [{
value: "moto",
passed: true
},{
value: "boat",
passed: false
}, {
value: "car",
passed: true
}]
console.log(data.reduce((accum, obj) =>
obj.passed
? accum.concat(obj.value)
: accum
, []))
const list =[
{
name:'Raj'
,
age:40
},{
name:'Raj 2'
,
age:20
},{
name:'Raj 3'
,
age:30
},{
name:'Raj 4'
,
age:20
}]
const result = list.reduce((a, c) => c.age>25 ? (a.push(c.name), a) : a, []);
console.log(result)