shaimo
shaimo

Reputation: 376

reduce on new Array not executing correctly

I need to execute a reduce function not on members of an array but rather just on the indices. I tried the following:

const len = 4;
const arr = new Array(len);
const total = arr.reduce((accum, dummy, index) => calculate(accum, index), 0);

This doesn't work. I tried adding some printouts and it seems that the function in the reduce statement never gets called.

If however I replace arr with:

const arr = [0,1,2,3];

then it works fine. What am I missing? The length of the array as I use it is indeed verified to be 4, so why isn't it executing the function 4 times as it should?

Upvotes: 0

Views: 42

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 370679

new Array(len) creates an array with a length property of len, but without any array index own-properties:

const arr = new Array(3);
console.log(arr.hasOwnProperty(1));

This is called a sparse array, and should almost always be avoided because creating them produces odd results like you're experiencing. You can .fill the array first so that each array index value from 0 to the length - 1 of the array is assigned a value:

const arr = new Array(3).fill(0);
console.log(arr.hasOwnProperty(1));

Then the reduce will be able to iterate over the array.

As the specification says:

9. Repeat, while k < len,
  a. Let Pk be ! ToString(k).
  b. Let kPresent be ? HasProperty(O, Pk).
  c. ****If kPresent is true, then*****
    i. Let kValue be ? Get(O, Pk).
    ii. Set accumulator to ? `Call(callbackfn, undefined, « accumulator,   d. kValue, k, O »)`.

Since a spare array does not have any array index own-properties, the .reduce callback (named calllbackfn in the spec) is never called.

Upvotes: 3

Related Questions