1

Why array.reduce returns NaN when I add 3rd object? See example below. What am I missing?

var x =[ 
 {Sum: 1},
 {Sum: 2},
 {Sum: 3}
]; 

var y = x.reduce((total, value) => total.Sum + value.Sum);

console.log(y);  // Why output is NaN?


x =[ 
 {Sum: 1},
 {Sum: 2},
]; 

y = x.reduce((total, value) => total.Sum + value.Sum);

console.log(y); // output = 3

2
  • 2
    Because on the second iteration total will be just the number 3 and you're getting 3.Sum which is undefined. Commented Apr 13, 2020 at 13:57
  • 1
    Because in the second case .reduce only iterates once, which does not expose the mistake in your code. The mistake is only visible if .reduce iterates at least twice: a + b returns a number, which becomes the next value of total. And numbers don't have a Sum property. Commented Apr 13, 2020 at 13:57

2 Answers 2

2

You need either to return the same structure as both items,

var x = [{ Sum: 1 }, { Sum: 2 }, { Sum: 3 }],
    y = x
        .reduce((a, b) => ({ Sum: a.Sum + b.Sum })) // reduce with the same structure
        .Sum;                                       // get value

console.log(y);

or take an initialValue of Array#reduce for reducing, because you add a number and not a property.

var x = [{ Sum: 1 }, { Sum: 2 }, { Sum: 3 }],
    y = x.reduce((total, object) => total + object.Sum, 0); // start with zero

console.log(y);

Sign up to request clarification or add additional context in comments.

Comments

2

The reason why your code with 2 objects seems to work, is because when you use the reduce function with no initial value, the accumulator takes the first array value as its initial value, in this case { Sum: 1}. So on the first iteration of your reduce function, total.Sum + value.Sum is 1 + 2, which gives 3. There are no more objects in the array, the iteration ends, and the error is not seen.

However, once you have 3 objects, on the next iteration, your accumulator is no longer in object form, it is now a number (3). You then try to get total.Sum which now is 3.Sum, which means nothing.

For clarity, let's add the initial value of the accumulator as the second argument of your reduce function. Assuming you want a number to represent the total, let's use 0 to start off with.

As you move through the reduce function, you want to add the value of each value.Sum to your total, and then return the total. This should not be total.Sum, since total is not an object.

Here is a working example, with console logs for clarity as to what is happening in the reduce functions:

var x =[ 
 {Sum: 1},
 {Sum: 2},
 {Sum: 3}
]; 

var y = x.reduce((total, value) => {
	console.log('1 -->', total, value);
	return total + value.Sum
}, 0);

console.log('final y value -->', y); 


x =[ 
 {Sum: 1},
 {Sum: 2},
]; 

y = x.reduce((total, value) => {
	console.log('2 -->', total, value);
	return total + value.Sum
}, 0);

console.log('final y value -->', y); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.