Reduce

Hey ,

I'm thrilled to help you learn JavaScript. Unfortunately, you've landed on a page where you cannot access with your current purchase.

Please upgrade (use this link) access this content.

I'm super eager to help you learn more!

Reduce

reduce is an array method that helps you convert an array into a single value. It looks like this:

const callback = (accumulator, currentValue, index) => {
  // return something here
}
const result = array.reduce(callback, initialValue)

initialValue is the value you want to start with.

accumulator is the value returned from the previous iteration. It will be initialValue for the first iteration.

currentValue is array item in the current iteration.

Let’s go through some examples.

Summing numbers

Let’s say you have a list of numbers. You want to find the total sum of these numbers.

const numbers = [1, 2, 3, 4, 5]

Here’s the code to sum the numbers.

const total = numbers.reduce((acc, num) => acc + num, 0)
console.log(total) // 15

Let’s go through what happens, step by step.

First, you pass an initialValue to reduce. This initialValue should be 0 because:

  1. We want accumulator to be a number.
  2. We don’t want the initialValue to affect the sum.
Initial value set to 0
Initial value set to 0

accumulator will be initialValue in the first iteration. currentValue will be the first array item.

accumulator assigns as 0
accumulator assigns as 0
currentValue is the first item in the array
currentValue is the first item in the array

You need to return a value in the callback. This value will be used as the next accumulator. Since we want to sum numbers, we return the sum of accumulator and currentValue.

The next return value is calculated
The next return value is calculated

accumulator takes on the returned value in the second iteration. currentValue will be the second array item.

The previous return value is used as the next accumulator
The previous return value is used as the next accumulator
currentValue becomes the second item in the array
currentValue becomes the second item in the array

We return the sum of the two values we have, accumulator and currentValue. This process goes on until reduce loops through the entire array. The final value will be returned to the function call.

The return value is calculated and the process repeats
The return value is calculated and the process repeats

Reducing an array into an object

We’ll create the reduce method together for this example.

Let’s say we have an array of fruits. We want to know the number of each type of fruit.

const fruits = ['apple', 'apple', 'banana', 'banana', 'orange', 'pear', 'apple']

// What you want
// {
//   apple: 3,
//   banana: 2,
//   orange: 1,
//   pear: 1
// }

First, we should pass an empty object as the initialValue because we want to create an object.

const tally = fruits.reduce((accumulator, fruit) => {
  // Do something
}, {})

In the first iteration, accumulator will be {}. fruit will be apple.

In this first iteration, we know the accumulator doesn’t have the fruit yet. ({} doesn’t contain apple). Here, we want to add apple to accumulator. While adding apple to accumulator, we set the number of apples to 1.

const tally = fruits.reduce((accumulator, fruit) => {
  return accumulator[fruit] = 1
}, {})

In the second iteration, accumulator takes on the previously returned value. fruit is another apple:

  • accumulator: { apple: 1 }
  • fruit: apple

Here, we want to increase the number of apples in the accumulator. To do so, we need to check if the apple property exists in accumulator. If it does, we increase its value by 1.

const tally = fruits.reduce((accumulator, fruit) => {
  if (accumulator[fruit]) {
    accumulator[fruit] = accumulator[fruit] + 1
  } else {
    accumulator[fruit] = 1
  }

  return accumulator
}, {})

That’s it! The process repeats for other fruits. If you log tally, you’ll see the object we wanted.

{
  apple: 3,
  banana: 2,
  orange: 1,
  pear: 1
}

Let’s clean up the reduce function next. We can do so with ternary operators.

const tally = fruits.reduce((accumulator, fruit) => {
  const fruitCount = accumulator[fruit]
  fruitCount
    ? accumulator[fruit] = fruitCount + 1
    : accumulator[fruit] = 1
  return accumulator
}, {})

Flattening an array

Let’s say we have an array that contains arrays. We want to convert this array of arrays into a single array that contains all values. This process is called flattening.

const array = [
  [1, 2, 3, 4, 5],
  [6, 7, 8, 9, 10]
]

// What we want:
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

To flatten the array, we need to start the reduce with an array. This is because we want the output to be an array.

const flattened = array.reduce((accumulator, item) => {
  // Do something
}, [])

In the first iteration, accumulator will be an empty array. item will be an array that contains five items.

  • accumulator: []
  • item: [1, 2, 3, 4, 5]

We want to merge item into accumulator. We can use concat to do so.

const a1 = []
const a2 = [1, 2, 3, 4, 5]
const merged = a1.concat(a2)
console.log(merged) // [1, 2, 3, 4, 5]

This method works even if accumulator contains values.

const a1 = [1, 2, 3]
const a2 = [4, 5]
const merged = a1.concat(a2)
console.log(merged) // [1, 2, 3, 4, 5]

The reduce code looks like this:

const flattened = array.reduce((accumulator, item) => {
  return accumulator.concat(item)
}, [])

If you want to make it shorter, you can use the array spread operator.

const flattened = array.reduce(
  (accumulator, item) => [...accumulator, ...item], []
)