Reputation: 35
var a = [2,4,5,6,7]
a.reduce((acc,cur,i)=>acc,[])
//result : []
a.reduce((acc,cur,i)=>acc,[0,2])
//result (2) [0, 2]
a.reduce((acc,cur,i)=>acc[0],[0,2])
/*
VM410:1 Uncaught TypeError: Cannot read property '0' of undefined
at <anonymous>:1:26
at Array.reduce (<anonymous>)
at <anonymous>:1:3
*/
why am I getting error for the third one? Wondering how it works?
Upvotes: 1
Views: 4953
Reputation: 286
The reduce function works as a for loop, where a variable (acc) gets set at every iteration:
The first two examples you gave:
var a = [2,4,5,6,7]
a.reduce((acc,cur,i) => acc, [])
a.reduce((acc,cur,i) => acc, [0, 2])
Are equivalent to assigning the accumulator to itself at each iteration:
var acc = []; // [0, 2] in the second one
for(var i=0; i < a.length; i++){
acc = acc;
}
Whereas your last example:
a.reduce((acc,cur,i) => acc[0], [0, 2])
Is equivalent to assigning to acc its first value at each iteration:
var acc = [0, 2];
for(var i = 0; i < a.length; i++){
acc = acc[0];
}
Each iteration will assign to acc its first value. The first iteration will look like this:
acc = [0, 2];
i = 0
acc = acc[0] // 0;
The second iteration will then look like this:
acc = 0;
i = 1
acc = acc[0] // undefined;
Now acc has been assigned the value undefined as there is no such property 0 in the value held by acc. The third iteration will, therefore, look like this:
acc = undefined;
i = 2;
acc = acc[0]; // Error, no property '0' of undefined.
Upvotes: 2
Reputation: 17238
Your code does not return an array. However, the accumulator will be set to that value. So while you assume that acc
is an array, it is not after the first call to the accumulation function.
What you can do instead is something along the following lines:
var a = [2,4,5,6,7];
a.reduce((acc,cur,i) => {
acc.push(cur);
console.log(`iter ${i}, acc = ${JSON.stringify(acc)}.`);
return acc;
}
,[0,2]
);
Just make sure that your callback returns an array upon each invocation.
Upvotes: 2
Reputation: 475
An excerpt from mdn documentation for Array.reduce
initialValue -A value to use as the first argument to the first call of the callback. If no initialValue is supplied, the first element in the array will be used as the initial accumulator value and skipped as currentValue. Calling reduce() on an empty array without an initialValue will throw a TypeError.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
Upvotes: 1