JavaScript array methods are very popular and useful. However, for some reason, the reduce method is left behind in that hype train. People not only ignore it but also actively avoid it.
Whatever the reason is, I have made it my mission to show you how great and — most importantly — easy it is to use.
The JavaScript reduce method helps you convert an array into a single value.
Before getting started, I assume that you understand how callback functions work in JavaScript. If not, check out the JavaScript callback functions guide to learn more.
In this article, I would try my best to explain the basics behind the reduce method and how it works.
So let’s get down to it.
How Does reduce() Method Work
JavaScript’s reduce() method implements what is known as folding in math. To put it simply, folding means you reduce a list of numbers into a single value.
For instance, calculating the sum of a list of numbers is a great real-life example of folding.
Example: 1+2+3 = 6
When you calculate the sum of a list of numbers, you:
- Take the first number and add the second number to it.
- Keep the result in your mind.
- Take the second number and add it to the result.
- Keep the result in your mind.
- Take the third number and add it to the result.
- You repeat this process until you have summed up all the numbers in the list.
This is exactly how the reduce()
method works in JavaScript.
The reduction generally follows this procedure:
- Call a function on the first two elements of an array to get a partial result.
- Call the function on this partial result and the third element of the array to get a new partial result.
- Repeat this process until there are no values left in the array.
- Return the result.
Now you understand the working principle of the reduce()
method.
To learn how to use the reduce()
method, let’s start by learning its syntax.
JavaScript reduce() Method Syntax
The reduce method in JavaScript helps to execute a reducer function on each element of the array and returns a single output value. To put it simply, the reduce()
method reduces the array to a single value.
Syntax:
arr.reduce(callback(accumulator, currentValue), initialValue)
Here, arr
is an array.
callback
– The callback function to execute on each array element (except the first element if no initialValue
is provided).
Also, this function is commonly known as a reducer. This function has to return a value.
It takes in –
accumulator
– It accumulates the callback’s return valuescurrentValue
– The current element being passed from the array
initialValue
(optional) – A value that will be passed to callback()
on first call. If not provided, the first element acts as the accumulator
on the first call and callback()
won’t execute on it.
Kindly note, calling reduce()
on an empty array without initialValue
will throw TypeError.
To make more sense of this, let’s see an example.
How to Use the reduce() Method
Perhaps the easiest example to demonstrate reduce()
is by summing up numbers in an array of numbers.
const numbers = [1, 2, 3, 4] const sum = numbers.reduce(function(accumulator, currentValue) { return accumulator + currentValue }, 0) console.log(sum) //10
Here the reduce()
method takes a function that sums up two arguments accumulator
and currentValue
, where accumulator
represents the result so far and currentValue
is the current element.
The second argument in the reduce()
function is 0. This is the initial value we want the sum to start from.
Under the hood, here are the calculations made by this particular reduce()
method call:
0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
Here is a great illustration of the process:
By the way, the function passed into the reduce()
method call is an example of an inline callback function.
In total, there are 3 different ways to provide the function as an argument to the reduce()
method:
- Callback function
- Inline callback function
- Arrow function
These are important to understand because, with each approach, the code looks a bit different although it produces the exact same result.
Furthermore, if you are using other array methods like map()
or filter()
, you are going to benefit from understanding these types of functions.
The 3 Types of Reducer Functions
As you now know, the reduce()
method takes a function argument.
This function can be a callback function, an inline callback function, or an arrow function.
By the way, these 3 types of functions are not only related to the reduce()
method. Instead, these types of functions can be used anywhere where you pass a function as an argument to another function.
These types of argument functions look different but behave the same way.
You should pick one based on the context.
- A callback is useful when you use the functionality multiple times.
- An inline callback is useful if you only need the reducer functionality once.
- An arrow function is a more concise way to write an inline callback function. Arrows functions were introduced in ES6.
Also Read: Arrow Functions in JavaScript
Let’s take a look at each type of reducer function mentioned above.
1. Callback Function
In JavaScript, a callback function is a function passed as an argument into another function (or method).
To use a callback function with the reduce()
method, you need to:
- Have an array of values.
- Specify a separate reducer function.
- Pass the reducer as an argument to the
reduce()
method call.
For instance, let’s calculate the sum of an array of numbers this way:
const numbers = [1, 2, 3, 4] function add(x, y) { return x + y } const sum = numbers.reduce(add, 0) console.log(sum) //10
As you can see, here we have a separate function called add
which we pass into the reduce()
method.
The add
argument is an example of a callback function. This argument add
is a reference to the actual implementation of the add()
function.
In this case, you do not need to provide any arguments because the reduce()
method does it on your behalf.
Next, let’s take a look at what is an inline callback in JavaScript.
2. Inline Callback Function
An inline callback function is a callback that is implemented directly into the function call. The word inline literally means “in-line”, that is, defined on the same line where it is called.
An inline callback is useful because you do not need to specify a separate function for the reduce()
method. Instead, you can create a one-time function directly into the reduce()
method call.
This is good practice if you only need the functionality once. It would not make any sense to leave unused functions hanging in the codebase.
Let’s see an example of using the reduce()
method with an inline callback function:
const numbers = [1, 2, 3, 4] const sum = numbers.reduce(function(x, y) { return x + y }, 0) console.log(sum) //10
Here the functionality for adding up two numbers is implemented directly into the reduce()
method call.
Although this makes the code nice and short, you can do things even better by using arrow functions.
3. Arrow Function
In JavaScript, an arrow function is a shorthand for a function expression.
It can make reduce()
method calls way more readable and concise. For instance, let’s repeat summing up an array of numbers once more using an arrow function:
const numbers = [1, 2, 3, 4] const sum = numbers.reduce((x, y) => x + y) console.log(sum) //10
Fabulous!
This piece of code looks quite professional, doesn’t it?
Next, let’s discuss closely related built-in array functions map()
and filter()
.
Use reduce() like map()
You can use the reduce()
method to complete a task you would do with the map()
method.
In short, the map()
method loops through an array and transforms it into another array by calling a function on each element in the array.
Here is an example of using the map()
method:
const numbers = [1, 2, 3, 4] const squaredNums = numbers.map(n => n * n) console.log(squaredNums) //[ 1, 4, 9, 16 ]
But this is something you could do with the reduce()
method as well.
For example, let’s square a list of numbers:
const numbers = [1, 2, 3, 4] const squaredNums = numbers.reduce((squares, x) => { squares.push(x * x) return squares }, []) console.log(squaredNums) //[ 1, 4, 9, 16 ]
In this case, it would actually make more sense to use the map() method because it is way simpler.
Let’s take a look at another commonly used array method, filter()
, and its relationship to the reduce()
method.
Use reduce() like filter()
In JavaScript, you can use the filter()
method to filter out values of an array. For example, let’s filter out all the odd values from an array of numbers:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] const evenNums = numbers.filter(x => x % 2 == 0) console.log(evenNums) //[ 2, 4, 6, 8, 10 ]
What you might not think about is you can achieve the same result using the reduce()
method.
For example:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] const evenNums = numbers.reduce((evens, x) => { if (x % 2 == 0) evens.push(x) return evens }, []) console.log(evenNums) //[ 2, 4, 6, 8, 10 ]
But as you can see, this is rather verbose compared to the filter()
approach. Thus, it is in fact a better idea to use the filter()
method in this particular task.
But why was it worth mentioning the map()
and the filter()
methods?
Let me show you when it can be better to use reduce()
instead of map()
or filter()
.
reduce() vs map() / filter()
In the context of mapping/filtering, you should use the functions map()
and filter()
by default. However, if you are combining these two, you should consider using the reduce()
method.
This is because if you chain a filter()
call with a map()
call, you are looping through the array twice.
But why loop twice if once is enough?
Let me show you an example.
In this example, we are going to combine the two examples which we have seen previously.
In other words, given an array of numbers, let’s create a new array with only the even numbers squared.
Here is how it looks in code:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] const evenSquared = numbers.filter(x => x % 2 == 0).map(x => x * x) console.log(evenSquared) //[ 4, 16, 36, 64, 100 ]
This works perfectly, and the code does not look bad either.
The .filter().map()
chain is readable and concise. But you might consider making the code run faster by combining the two loops, filter()
and map()
, into a single loop by using reduce()
.
Here is how it looks in code:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] const evenSquared = numbers.reduce((res, x) => { if(x % 2 == 0) res.push(x * x) return res }, []) console.log(evenSquared) //[ 4, 16, 36, 64, 100 ]
This only loops through the array once.
However, the code is now rather unreadable and verbose. If there is no clear benefit to doing it this way, you should use an approach that is more readable.
Now that you have extensively used the reduce()
method, let’s see a couple of mistakes you should avoid.
Mistakes to Avoid with reduce() Method
Once you have had enough practice, using the reduce()
method becomes easy for you.
Here are two common pitfalls that can cause a lot of headaches when using the reduce()
method.
Forgetting the Initial Value
Always remember to set the initial value as the second argument in the reduce()
method call.
If you do not, the default initial value is used. This default value is the array element at the index of 0
. Usually, the default value is actually what you want.
Forgetting to Return
A really common pitfall of using the reduce()
method is forgetting to return a value from the reducer function.
The reducer function must return a value. This is because the return value is treated as a partial result. If there is no return value, the reduce()
method does not work.
Notice that if you are using a single-line arrow function as the reducer, you do not need to use the return
keyword.
This is because a one-liner arrow function expression implicitly returns the value.
Practical Examples
Here are two practical examples of using the reduce()
method in JavaScript.
Group Values: A Tally with reduce()
You can use the reduce()
method to group array values by their frequency.
For example, given a list of fruits, let’s create an object that groups the fruits by how many times they occur in the array,
Here is how it looks in code:
const fruits = [ 'apple', 'orange', 'orange', 'apple', 'cherry', 'grape', 'banana', 'cherry', 'orange' ] const tally = fruits.reduce( (tally, fruit) => { tally[fruit] = (tally[fruit] || 0) + 1 return tally } , {}) console.log(tally) //{ apple: 2, orange: 3, cherry: 2, grape: 1, banana: 1 }
Flatten an Array
If you are dealing with a 2D array, you can use the reduce()
method to flatten it.
This works such that the reduce()
method concatenates each sub-array to a single 1D array.
For example:
const nums2D = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] const flat = nums2D.reduce((nums1D, row) => nums1D.concat(row), []) console.log(flat) //[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Advanced Use of reduce() Method
So far you have seen how to use the reduce()
method with this syntax:
arr.reduce(callback(accumulator, currentValue), initialValue)
However, you can also add some optional arguments to the reducer function.
The full syntax of using the reduce()
method is actually:
arr.reduce(callback(accumulator, currentValue, currentIndex, array), initialValue)
Where:
currentIndex
is the optional index of the current array element.array
is the optional array on whichreduce()
is being called.
Here is an example of a situation in which you can specify the currentIndex
.
Let’s say you have an array of names that represent people standing in a line.
Now you want to convert this array of names into an object of position number and the person’s name.
Here is how to do it:
const names = ["Ram", "Gopal", "Hari"] const queue = names.reduce(function(namesData, name, nameIndex) { namesData[nameIndex + 1] = name return namesData }, {}) console.log(queue) //{ '1': 'Ram', '2': 'Gopal', '3': 'Hari' }
Now each name is associated with a position in the queue.
As you can see, the code is quite clean as you do not need to track the index yourself. Instead, the reducer function takes care of that part.
Usually, you are not going to need these optional parameters.
However, it is good to know they exist.
Conclusion
In this tutorial, you learned how to use the JavaScript reduce()
method.
Here is a brief summary of what was discussed in this lesson:
- How to use a JavaScript
reduce()
method - The purpose of the second argument of the reduce method – it tells the reducer function what initial value to use
- A few examples of the JavaScript
reduce()
method in practice - The differences between the
map
,filter
andreduce
methods in JavaScript (or any other programming language)
Resource
- Array Reduce in 100 seconds
- JavaScript Array reduce() Method Examples – By programiz
- JavaScript Array Reduce Method – 10 Examples
- JS reduce() method and its use-cases
Add comment