All questions

Array.prototype.reduce

Premium

Array.prototype.reduce

Implement Array.prototype.myReduce — your own version of Array.prototype.reduce. reduce walks an array left-to-right, folding each element into a running accumulator, and returns whatever's left at the end. You've used it to sum numbers, build lookup objects, or flatten arrays — your job is to write the loop yourself, name it myReduce, and hang it off Array.prototype so [1, 2, 3].myReduce(fn, 0) works.

The interesting part isn't the loop. It's the four-way matrix the spec defines: the caller may or may not pass an initialValue, and the array may or may not be empty. Three of those four cells have a normal answer; one of them throws a TypeError. You also need to handle sparse arrays — the kind with holes left by [1, , 3] or new Array(5) — by skipping the empty slots.

Signature

// Hung off Array.prototype.
Array.prototype.myReduce = function (callback, initialValue) {
  // callback(accumulator, currentValue, currentIndex, array) => nextAccumulator
  // initialValue is optional. Returns the final accumulator.
};

Examples

// Basic sum, with a seed.
[1, 2, 3].myReduce((a, b) => a + b, 0); // 6

// No seed — first element becomes the accumulator, iteration starts at index 1.
[1, 2, 3].myReduce((a, b) => a + b); // 6

// Sparse array — the hole at index 1 is skipped.
[1, , 3].myReduce((a, b) => a + b, 0); // 4

// Empty array with no seed — throws.
[].myReduce((a, b) => a + b); // TypeError: Reduce of empty array with no initial value

Notes

  • No initialValue, non-empty array — the accumulator starts at the first present element and iteration begins at the next index.
  • No initialValue, empty array — throw TypeError("Reduce of empty array with no initial value").
  • initialValue provided, empty array — return the initialValue; the callback never runs.
  • Sparse arrays — holes ([1, , 3]) are not the same as explicit undefined ([1, undefined, 3]). Skip holes; visit explicit undefineds. Use k in this to tell them apart.
  • Detecting "no initialValue" — use arguments.length, not initialValue === undefined. A caller passing undefined explicitly is different from omitting the argument.
  • Don't worry about typed arrays, async callbacks, or reduceRight. Focus on the spec's edge cases for the plain synchronous Array.prototype.reduce.

Unlock the solution & editor

  • Runnable editor + tests

    Solve in the browser with instant Jest feedback.

  • Detailed solutions

    Walkthroughs, edge cases, and complexity notes.

  • Multi-framework variants

    React, Vue, Vanilla, Angular — same question, different stacks.

Upgrade to Premium