Codectionary / Developer documentation / JavaScript

reduce() and reduceRight()

reduce() carries a result from one callback call to the next. Use it when several items contribute to one total, lookup or other accumulated value. reduceRight() follows the same process from the end of the array. If a loop explains the calculation more clearly, use a loop.

Syntax

items.reduce((accumulator, item, index, array) => nextAccumulator, initialValue)
items.reduceRight((accumulator, item) => nextAccumulator, initialValue)

Examples

Total the study time

Start at 0 so an empty reading list also has a sensible total.

const lessons = [{ minutes: 12 }, { minutes: 8 }, { minutes: 15 }];
const total = lessons.reduce((minutes, lesson) => minutes + lesson.minutes, 0);
console.log(total); // 35
console.log([].reduce((sum, value) => sum + value, 0)); // 0
try {
  [].reduce((sum, value) => sum + value);
} catch (error) {
  console.log(error.name); // TypeError
}

Count topics without inherited-key collisions

A null-prototype object starts with no inherited properties, so a topic called constructor can be counted too. Return the accumulator after updating it.

const topics = ["arrays", "functions", "arrays", "constructor"];
const counts = topics.reduce((result, topic) => {
  result[topic] = (result[topic] ?? 0) + 1;
  return result;
}, Object.create(null));
console.log(counts.arrays); // 2
console.log(counts.functions); // 1
console.log(counts.constructor); // 1

See when direction matters

Concatenating text gives different results in opposite directions. Both methods leave this input array in its original order.

const parts = ["A", "B", "C"];
console.log(parts.reduce((text, part) => text + part, "")); // ABC
console.log(parts.reduceRight((text, part) => text + part, "")); // CBA
console.log(parts); // ["A", "B", "C"]

Parameters and values

  • callback: Receives the accumulator, current item, index and original array. Return the accumulator for the next call. Empty slots are skipped.
  • initialValue (optional): With an initial value, processing starts at the first present item. Without one, reduce uses the first present item as the accumulator and starts after it. reduceRight mirrors this from the end.
  • Return value and empty arrays: Returns the final accumulator. With no items to process, an initial value is returned unchanged. Without an initial value and with no present items, a TypeError is thrown.

Best practices

  • Choose an initial value that matches the result you want: 0 for a sum, an array for a list, or a suitable object or Map for a lookup.
  • Return the accumulator on every path, including after changing its properties.
  • Use map() for one output per item and filter() for selection. reduce() is not a shorter replacement for every loop.
  • Repeatedly spreading a growing accumulator copies more data on every iteration. For a large lookup, update a fresh accumulator or use a straightforward loop.

Runtime & versions

Browsers and JavaScript runtimes. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

ECMAScript specification

Specifications & further reading