Silvia Pan Logo
June 06, 2019

How to Use JavaScript's Reduce

JavaScript’s reduce function is used on each element of an array to reduce the array into a single value.

The reduce function can take in two parameters: a callback function and an optional initial value.

// Reduce works with just a callback function
const result = array.reduce(callback);

// You can also specify an initial value
const result = array.reduce(callback, initialValue);

Callback function

The callback function contains the code for how to reduce the array. It gets executed for each value in the array and takes in four arguments.

  • Accumulator (required) - accumulated return value from each callback function. If an initialValue is provided, the accumulator equals the initialValue. Otherwise, it is equal to the value of the first element in the array.
  • Current value (required) - value of current element
  • Current index (optional) - index of the current element. If an initialValue is provided, the current index starts at 0. Otherwise, the current index starts at 1.
  • Array (optional) - Array being processed in the reduce function

Basic reduction

We can use reduce to sum up an array of numbers.

const numbers = [1, 2, 3, 4];
const sum = numbers.reduce(
  (accumulator, currentValue) => accumulator + currentValue
);
console.log(sum); // 10

The example above uses ES6 arrow functions. In ES5, this can be written as:

let sum = numbers.reduce(function(accumulator, currentValue) {
  return accumulator + currentValue;
});

If you want to learn more about why the arrow function doesn’t need an explicit return like it does in ES5 please check out this tutorial on return values.

Breakdown of callback function

The reduce function takes in two arguments: callback and initialValue. In the sum reduction, there is no initialValue so we will focus only on how the callback function works.

The callback function is (accumulator, currentValue) => accumulator + currentValue and contains the accumulator and currentValue arguments.

Because there is no initialValue the accumulator will equal to the first value of the array, i.e. 1. The currentValue is the next number in the array, i.e. 2.

The two values are added together and then the sum of those two numbers are returned to be used as the accumulator. The accumulator is now equal to the sum of 3 and the currentValue is 3.

This process continues until the end of the array is reached.

// Process of reducing the array of numbers
accumulator + currentValue = newAccumulator
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10

Introduction of an initialValue

How would this be different if there were an initialValue of 10?

const numbers = [1, 2, 3, 4];
const initialValue = 10;
const sum = numbers.reduce(
  (accumulator, currentValue) => accumulator + currentValue,
  initialValue
);
console.log(sum); // 20

When there was no initialValue, the accumulator was first set to 1 and currentValue was 2. However, now the accumulator is set to 10 and the currentValue is 1.

// Process of reducing the array of numbers with an initialValue
initialValue + currentValue = accumulator
accumulator + currentValue = newAccumulator
10 + 1 = 11
11 + 2 = 13
13 + 3 = 16
16 + 4 = 20

Mathemetical operations

You can do more than just add the numbers. Try what will happen if you replace accumulator + currentValue with any other operation.

const numbers = [1, 2, 3, 4];
const initialValue = 5;
const product = numbers.reduce(
  (accumulator, currentValue) => accumulator * currentValue
);
const exponential = numbers.reduce(
  (accumulator, currentValue) => accumulator ** currentValue,
  initialValue
);

Reduction with array of objects

The reduce function can be used for data types in addition to numbers.

Let’s say you run an online shop. When the shopper views her cart, she wants to see the total cost of the items.

Each item’s information is represented by an object with the item’s id, name, quantity, and unit price.

const shoppingCart = [
  { id: 1, name: 'balloon', quantity: 4, unitPrice: 2.25 },
  { id: 2, name: 'plate', quantity: 10, unitPrice: 0.35 },
  { id: 3, name: 'cup', quantity: 6, unitPrice: 0.25 },
];

The callback function loops through each element of the array. To get the subtotal for each item we would do quantity * unitPrice. The element is an object and you can use its keys to get the values you need. Therefore, you would do currentValue.quantity * currentValue.unitPrice to get the subtotal.

const shoppingCart = [
  { id: 1, name: 'balloon', quantity: 4, unitPrice: 2.25 },
  { id: 2, name: 'plate', quantity: 10, unitPrice: 0.35 },
  { id: 3, name: 'cup', quantity: 6, unitPrice: 0.25 },
];

const total = shoppingCart.reduce(
  (accumulator, currentValue) =>
    accumulator + currentValue.quantity * currentValue.unitPrice
);

console.log(total); // '[object Object]3.51.5'

We’re taking the accumulator and adding it to each item’s subtotal, but the answer is not what we expected. Why doesn’t this reduction return the total as a number?

Use case for initialValue

We learned previously, if the there is no initial value declared then the first element of the array becomes the accumulator.

Without an initialValue, the function started with {id: 1, name: 'balloon', quantity: 4, unitPrice: 2.25} as the accumulator and continued to add values to this object.

accumulator + currentValue.quantity * currentValue.unitPrice = newAccumulator

// First adds the subtotal (number) to an object, resulting in a string
{id: 1, name: 'balloon', quantity: 4, unitPrice: 2.25} + 10 * 0.35 = '[object Object]3.5'

// Then adds the subtotal (number) to a string, resulting in a string
'[object Object]3.5' + 6 * 0.25 = '[object Object]3.51.5'

Including an initialValue of 0 will now return the correct result.

const total = shoppingCart.reduce(
  (accumulator, currentValue) =>
    accumulator + currentValue.quantity * currentValue.unitPrice,
  0
);
console.log(total); // 14

Powerful use for reduce

Reduce allows you to manipulate arrays in an endless number ways. One of my favorite uses for reduce is to change the array into an object.

This is useful for the times when I get data from an API endpoint and I want to get the value of a field without looping through the data each time.

Reducing an array into an object eliminates the need to traverse through the array and instead you can do object[key] to get whatever values you are searching for. Read about how to turn an array into an object.

© 2023 Silvia Pan