1

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?

4
  • 2
    First iteration acc = [0, 2] you return 0 (the number). Second iteration acc = 0 Commented Apr 12, 2020 at 16:21
  • 1
    your return value on each iteration becomes acc for next iteration, so when you do acc[0] which is 0 so on next iteration you're doing 0[0] which returns undefined and then undefined[0] is syntax error Commented Apr 12, 2020 at 16:25
  • @CodeManiac no 0[0] is fine - it produces undefined. Next iteration there us a TypeError because of undefined[0] Commented Apr 12, 2020 at 16:29
  • @VLAZ ahh thanks for pointing fixed my comment Commented Apr 12, 2020 at 16:30

3 Answers 3

3

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.

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

Comments

2

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.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.