The Array.reduce Method Part 4 - Reduce in Reverse
Greetings, friends! This is Part 4 of my tutorial series on the Array.reduce method in JavaScript! In this tutorial, I will discuss how to use the Array.reduceRight method to run the reduce
method in reverse.
Array.reduce vs Array.reduceRight
The main difference between the reduce
method and the reduceRight
method is that reduceRight
operates on an array in reverse. It iterates through an array from right to left, hence the name. You can think of the following as approximately equivalent:
array.reverse().reduce((a, c) => a + c, initialValue);
array.reduceRight((a, c) => a + c, initialValue);
I say approximately equivalent because the reduceRight
method was written to start at the end of the array and work backwards. It doesn't actually have an intermediate step where we reverse the array before running a reducer. That wouldn't be very performant. Perhaps it's better to say that we're iterating through an array backwards and executing an operation.
const array = [10, 20, 30, 40];
for (let i = array.length - 1; i >= 0; i--) {
console.log(array[i]);
}
/* OUTPUT:
40
30
20
10
*/
Let's look at an example where the reduceRight
method will return a different result than the reduce
method.
const array = ['pizza', 'is', 'life'];
const reduceResult = array.reduce(
(accumulator, currentValue) => accumulator + ' ' + currentValue
);
const reduceRightResult = array.reduceRight(
(accumulator, currentValue) => accumulator + ' ' + currentValue
);
console.log(reduceResult); // pizza is life
console.log(reduceRightResult); // life is pizza
Looks like two different results to me! Or, maybe they're the same 🤔. We'll ask some philosophers later what they think.
In both the reduce
and reduceRight
methods, we are concatenating each element of the array with a space and the next element of the array. The output string is different because we started at the end of the array when using the reduceRight
method.
Here is a tabular breakdown of what happens during each iteration of the reduce
method:
iteration | accumulator | current value | return value |
---|---|---|---|
1st | 'pizza' | 'is' | 'pizza is' |
2nd | 'pizza is' | 'life' | 'pizza is life' |
Remember! Since we did not pass initialValue
as the second parameter to the reduce
method, the accumulator starts with the first element of the array. This also means we'll have one less iteration of the reducer.
Here is a tabular breakdown of what happens during each iteration of the reduceRight
method:
iteration | accumulator | current value | return value |
---|---|---|---|
1st | 'life' | 'is' | 'life is' |
2nd | 'life is' | 'pizza' | 'life is pizza' |
Since we did not pass initialValue
as the second parameter to the reduceRight
method, the accumulator starts with the last element of the array, which is an important distinction.
Function Definition for Array.reduceRight
The reduceRight
function definition is exactly the same as the reduce
method. It takes two parameters: a callback function and an initialValue
(which is optional).
reduceRight(callbackFn, initialValue)
The callback function passed into the reduceRight
method is also known as a "reducer" callback function, or simply, "reducer." This callback function can accept two, three, or four parameters just like the reduce
method.
If we expand the function definition to include the various parameters we can pass into the reducer callback function, we get the following:
reduceRight((accumulator, currentValue) => { /* ... */ }, initialValue )
reduceRight((accumulator, currentValue, index) => { /* ... */ }, initialValue )
reduceRight((accumulator, currentValue, index, array) => { /* ... */ }, initialValue)
Again, this is exactly the same as the function definition for the Array.reduce method.
Conclusion
We have now learned how to use the reduceRight
method to run a reducer on an array in reverse order. This method will prove very useful for making "compose" operations that we will discuss in the next lesson. Do you think "pizza is life" or "life is pizza?" 🍕