DEV Community

Cover image for JavaScript Reduce Method Made Simple
Alex Devero
Alex Devero

Posted on • Originally published at blog.alexdevero.com

JavaScript Reduce Method Made Simple

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.

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

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

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.

// 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
Enter fullscreen mode Exit fullscreen mode

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.

// 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
Enter fullscreen mode Exit fullscreen mode

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.

// 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
Enter fullscreen mode Exit fullscreen mode

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

// 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
Enter fullscreen mode Exit fullscreen mode

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.

// 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]
Enter fullscreen mode Exit fullscreen mode

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.

// 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
// }
Enter fullscreen mode Exit fullscreen mode

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.

// 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 }
// }
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (1)

Collapse
tevdevelops profile image
Tevin Rivera • Edited on

Great and to the point article. Thanks for the brush up. The examples had a great pace to them, but I did want to note that your example on how to find the min of an array (const numbers = [1,3,5,7,9,11]) says that it will return 6 instead of 1

And maybe that is a good thing because I was looking at it over and over until I had to open my console and double check that it should be 1. Haha felt like I was back in school again.

And also, maybe you should include a note about how If initialValue is specified, that also causes currentValue to be initialized to the first value in the array. If initialValue is not specified, previousValue is initialized to the first value in the array, and currentValue is initialized to the second value in the array.