azhahes.s
azhahes.s

Reputation: 35

How reduce in javascript work if initial value is array

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

Answers (3)

Elias Faraone
Elias Faraone

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

collapsar
collapsar

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

Varun Goel
Varun Goel

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

Related Questions