The JavaScript reduce() Function

By

Learn how the JavaScript reduce() method runs a callback over every array item to compute a single result, using an accumulator and an optional initial value.

~~~

reduce() runs a callback on every item of an array to compute a single result out of it. A sum, a product, an object, whatever you build up along the way.

Where map() gives you back a new array, reduce() gives you back one value. That’s the whole point: you have a list, you want one thing out of it.

This is the signature:

a.reduce((accumulator, currentValue, currentIndex, array) => {
  //...
}, initialValue)

The accumulator is the value carried over from one iteration to the next. Whatever the callback returns becomes the accumulator for the next item. If initialValue is specified, accumulator in the first iteration will equal that value.

Example:

[1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => {
  return accumulator * currentValue
}, 1)

// iteration 1: 1 * 1 => return 1
// iteration 2: 1 * 2 => return 2
// iteration 3: 2 * 3 => return 6
// iteration 4: 6 * 4 => return 24

// return value is 24

Most of the time you only need the first two parameters, and the code gets much shorter. Here’s the classic use case, summing numbers:

const expenses = [220, 300, 130]

const total = expenses.reduce((sum, amount) => sum + amount, 0)
//650

We start the accumulator at 0, and each iteration adds one expense to it.

What if you omit the initial value?

The initial value is optional. If you leave it out, reduce() uses the first array item as the accumulator and starts iterating from the second:

[220, 300, 130].reduce((sum, amount) => sum + amount)
//650

Same result here, so it looks harmless. But there’s a catch.

Be careful with empty arrays

Call reduce() without an initial value on an empty array and it throws:

[].reduce((sum, amount) => sum + amount)
//TypeError: Reduce of empty array with no initial value

There’s no first item to use as the accumulator, so JavaScript gives up.

This bites you when the array comes from somewhere else, a filter, an API response, and it happens to be empty that one time. The fix is to always pass an initial value:

[].reduce((sum, amount) => sum + amount, 0)
//0

My advice is to just always provide it. It makes the code more predictable, and it documents what type of value you’re building.

~~~

Related posts about js: