JavaScript Reduce Method Made Simple
Tags: javascript, webdev, beginners, tutorial
Published: 2021-11-29 06:33:22

The JavaScript reduce method is one of the most used array methods. It is also a part of functional programming. In this tutorial, you will learn what the reduce method is and how it works. You will also learn how to use this method and what are some of the things it can do with it.

## Introduction

The `reduce()` method is one of the features that was add to JavaScript in ES6 (ECMAScript 2015). It quickly became one of the most often used array methods. What this method does is it reduces a given array into a single value by executing a reducer function you provided. It essentially reduces an array into a single value.

## The syntax

The syntax of reduce method is simple. This method takes two parameters. The first one is a callback function. The callback function will be invoked for every element in the array. When it is invoked, the `reduce()` passes four parameters into this callback function.

These parameters are `accumulator`, `currentValue`, `index` and the original array. The `accumulator` is the value `reduce()` returns after the last call of the callback. One exception is when `reduce()` runs for the first time. In this case, the value of `accumulator` is the value you provided as the `initialValue` argument.

The `currentValue` is the current element being processed in a given array. The `index` is the index of the current element that is being processed in the array. If you provide the `initialValue` this index starts at 0. If you omit the `initialValue`, index will start at 1. Last parameter is the array that is being processed.

The second parameter of `reduce()` method is the `initialValue`. This is the initial value you want the reduce method to start with.
This initial value is used as the first argument for the first call of the callback function. If you omit it, `reduce()` will use the first element in the array as the initial value.

```JavaScript
// Syntax of reduce():
someArray.reduce(callback, initialValue);

// Hypothetical reducer callback function:
const reducer = (accumulator, currentValue, index) => {
  // ... do something
}
```

## Usage

The reduce method is usually used for operations such as calculating total sums and averages or finding minimum and maximum values in a given array. That said, you can also use `reduce()` for other things. For example, to change structure of objects or to flatten two-dimensional arrays.

### Summing values in an array

One of the simplest examples of using the `reduce()` method is summing values in an array. This can be done with a simple callback function in which we take the `currentValue` and add it to the `accumulator`. This will repeat for every iteration. `currentValue` will be added to the increasing value of the `accumulator`.

After the last number in the array is processed, `reduce()` will return the accumulated value of `accumulator`. If we want the reduce to start from a different number than 0 we can set that starting number as the initial value. Otherwise, we can set the initial value to 0 and `reduce()` will start with that.

```JavaScript
// Create array of numbers:
const numbers = [1, 3, 5, 7, 9, 11];

// Sum the numbers array:
const sum = numbers.reduce((accumulator, currentValue, index) => accumulator + currentValue, 0)
// For each iteration, add the "currentValue"
// to the value of the "accumulator".

// Log the result:
console.log(sum)
// 36
```

### Finding averages

We can also use [if...else] statement to return different results from the callback function. This is handy for example when we want to get the average of numbers in an array. We can add a `if...else` statement that will check if the currently processed item is the last item of the array.

This check will use the index of currently processed item and the length of the array. If the currently processed item is the last item in the array we will divide the accumulated value by the length of the array. If it is not the last item, we will return the accumulated value.

Before each check, we will add the currently processed value to the accumulator.

```JavaScript
// Create array of numbers:
const numbers = [1, 3, 5, 7, 9, 11];

// Find the average:
const average = array.reduce((accumulator, currentValue, index, array) => {
  // For each iteration, add the "currentValue"
  // to the value of the "accumulator".
  accumulator += currentValue

  // Check if currentItem is the last item in the array:
  if (index === array.length - 1) {
    // If it is, divide the accumulated value
    // by the length of the array and return the result:
    return accumulator / array.length
  } else {
    // Otherwise, return the accumulated value:
    return accumulator
  }
})

// Log the result:
console.log(average)
// 6
```

### Finding minimum and maximum values

We can use reduce to find the minimum value in an array by comparing the value of `accumulator` and `currentValue` arguments. If the value of `accumulator` is less than the value of `currentValue`, we will return the `accumulator`. Otherwise, we will return the `currentValue`.

```JavaScript
// Create array of numbers:
const numbers = [1, 3, 5, 7, 9, 11];

// Find minimum value:
const min = numbers.reduce((accumulator, currentValue) => {
  // If the value of "accumulator" is less than "currentValue"
  // return the "accumulator", else return the "currentValue":
  return accumulator < currentValue ? accumulator : currentValue;
})

// Log the result:
console.log(min)
// 6
```

We can easily find the maximum value by switching the condition inside the callback function.

```JavaScript
// Create array of numbers:
const numbers = [1, 3, 5, 7, 9, 11];

// Find maximum value:
const max = numbers.reduce((accumulator, currentValue) => {
  // If the value of "accumulator" is greater than "currentValue"
  // return the "accumulator", else return the "currentValue":
  return accumulator > currentValue ? accumulator : currentValue;
})

// Log the result:
console.log(max)
// 11
```

### Flattening arrays

The reduce method can be also helpful when we want to flatten multi-dimensional arrays. We can do this by using the [concat()] method on the `accumulator`, passing the `currentValue` as an argument to the `concat()` method. Note that this simple solution will work only with two-dimensional arrays.

If you have an array with more than two dimensions, the [flat()] method will do the job.

```JavaScript
// Create array of numbers:
const numbers = [1, [3, 5], [7, 9, 11], [13, 15, 17]];

// Flatten an array:
const numbersFlattened = numbers.reduce((accumulator, currentValue) => {
  // Concatenate the accumulator with the currentValue:
  return accumulator.concat(currentValue);
}, [])

// Log the result:
console.log(numbersFlattened)
// [1,  3,  5,  7, 9, 11, 13, 15, 17]
```

### Counting number of occurrences

We can use the reduce method also for tasks such as counting the number an item occurred in an array. We can do this by setting the initial value to an empty object. During each iteration, we will check if currently processed item is an existing property of that object.

If it is, we will change the value of this property by 1. This is the number of occurrences. If the item is not an existing property, we will add it, with a value of 1. Then we will return the `accumulator` object. At the end, we will get an object with all items as properties and number of occurrences as values.

```JavaScript
// Create array of numbers:
const fruit = ['apple', 'pear', 'lemon', 'avocado', 'apple', 'banana', 'pear', 'apple', 'pineapple'];

// Count the number of occurrences:
const occurrences = fruit.reduce((accumulator, currentItem) => {
  // Check if item exists in accumulator object:
  if (currentItem in accumulator) {
    // If so, increase the number of occurrences by 1:
    accumulator[currentItem] = accumulator[currentItem] + 1
  } else {
    // Else register new occurrence:
    accumulator[currentItem] = 1
  }

  // Return the accumulator object:
  return accumulator
}, {})

// Log the result:
console.log(occurrences)
// {
//   apple: 3,
//   pear: 2,
//   lemon: 1,
//   avocado: 1,
//   banana: 1,
//   pineapple: 1
// }
```

### Changing shape of objects inside arrays

When we reduce an array we don't have to reduce it to a single value. We can also change its content. For example, if it is an array of objects we can change the shape of those objects. The returned value will be still an array, only the shape of the objects inside the array will be different.

```JavaScript
// Create array of numbers:
const records = [
  { name: 'Joe', grade: 'A' },
  { name: 'Tom', grade: 'B' },
  { name: 'Sandra', grade: 'B' },
  { name: 'Joel', grade: 'C' },
  { name: 'Victoria', grade: 'A' }
]

// Change the structure of objects in "records" array:
const updatedRecords = records.reduce((accumulator, currentItem) => {
  // During each iteration, transform currently processed object
  // into this shape:
  accumulator[currentItem.name] = {
    grade: currentItem.grade,
    passed: ['A', 'B'].includes(currentItem.grade)
  }

  // Return the modified object:
  return accumulator
}, {})

// Log the result:
console.log(updatedRecords)
// {
//   Joe: { grade: 'A', passed: true },
//   Tom: { grade: 'B', passed: true },
//   Sandra: { grade: 'B', passed: true },
//   Joel: { grade: 'C', passed: false },
//   Victoria: { grade: 'A', passed: true }
// }
```

## Conclusion: JavaScript Reduce Method Made Simple

Even thought the syntax of reduce method is simple, it can help us do interesting things with arrays. I hope that this tutorial helped you understand what the `reduce()` method does, how it works and how to use it.

[if...else]: https://blog.alexdevero.com/javascript-if-else-statement/
[concat()]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
[flat()]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat