Say I want to sum a.x
for each element in arr
.
arr = [{x:1},{x:2},{x:4}]
arr.reduce(function(a,b){return a.x + b.x})
>> NaN
I have cause to believe that a.x is undefined at some point.
The following works fine
arr = [1,2,4]
arr.reduce(function(a,b){return a + b})
>> 7
What am I doing wrong in the first example?
After the first iteration your're returning a number and then trying to get property x
of it to add to the next object which is undefined
and maths involving undefined
results in NaN
.
try returning an object contain an x
property with the sum of the x properties of the parameters:
var arr = [{x:1},{x:2},{x:4}];
arr.reduce(function (a, b) {
return {x: a.x + b.x}; // returns object with property x
})
// ES6
arr.reduce((a, b) => ({x: a.x + b.x}));
// -> {x: 7}
Explanation added from comments:
The return value of each iteration of [].reduce
used as the a
variable in the next iteration.
Iteration 1: a = {x:1}
, b = {x:2}
, {x: 3}
assigned to a
in Iteration 2
Iteration 2: a = {x:3}
, b = {x:4}
.
The problem with your example is that you're returning a number literal.
function (a, b) {
return a.x + b.x; // returns number literal
}
Iteration 1: a = {x:1}
, b = {x:2}
, // returns 3
as a
in next iteration
Iteration 2: a = 3
, b = {x:2}
returns NaN
A number literal 3
does not (typically) have a property called x
so it's undefined
and undefined + b.x
returns NaN
and NaN + <anything>
is always NaN
Clarification: I prefer my method over the other top answer in this thread as I disagree with the idea that passing an optional parameter to reduce with a magic number to get out a number primitive is cleaner. It may result in fewer lines written but imo it is less readable.