Q5: Implement a polyfill for Array.prototype.reduce().

Difficulty:BeginnerTopic:Array Methods

Answer

The reduce() method processes array elements and accumulates them into a single result.

The accumulator starts with the supplied initial value when one is provided. Otherwise, it starts with the first existing array element.

Array.prototype.myReduce = function (callback, initialValue) {
  if (this == null) {
    throw new TypeError("Array.prototype.myReduce called on null or undefined");
  }

  if (typeof callback !== "function") {
    throw new TypeError("Callback must be a function");
  }

  const array = Object(this);
  const length = array.length >>> 0;
  let index = 0;
  let accumulator;

  if (arguments.length >= 2) {
    accumulator = initialValue;
  } else {
    while (index < length && !(index in array)) {
      index++;
    }

    if (index >= length) {
      throw new TypeError("Reduce of empty array with no initial value");
    }

    accumulator = array[index++];
  }

  while (index < length) {
    if (index in array) {
      accumulator = callback(
        accumulator,
        array[index],
        index,
        array
      );
    }

    index++;
  }

  return accumulator;
};

console.log([1, 2, 3, 4].myReduce((sum, n) => sum + n, 0));
// 10

Important interview edge cases

Empty array with an initial value: returns the initial value.

Empty array without an initial value: throws a TypeError.

Array without an initial value: the first existing element becomes the initial accumulator, and iteration starts after that element.

The implementation preserves sparse-array behavior. As with the earlier examples, length >>> 0 is a simplified length conversion rather than an exact implementation of the ECMAScript abstract operations.

Reduce to group objects
const fruits = ["apple", "banana", "apple", "orange", "banana", "apple"];

const counts = fruits.myReduce((result, fruit) => {
  result[fruit] = (result[fruit] || 0) + 1;
  return result;
}, {});

console.log(counts);
// { apple: 3, banana: 2, orange: 1 }
💡 Reduce can build a new object by returning the updated accumulator on each iteration.
Key Takeaways
  • Reduce carries an accumulator across iterations.
  • Without an initial value, an empty array or an array containing only holes throws a TypeError.