reduceRight()

The JavaScript reduceRight() method runs a function on each element of the array from right to left (last to first), resulting in a single (reduced to) value. It works like reduce() but processes elements in reverse order, which can be important for certain operations where processing direction matters.

Syntax

const result = array.reduceRight(function(accumulator, currentValue, index, array) {
  // return accumulated value
}, initialValue);

Parameters:

  • function: Function to run on each element of the array, taking four possible arguments:
    • accumulator: The current total (accumulated) value, returned by the previous callback function call.
    • currentValue: The current array element being processed.
    • index (optional): The index position of the current array element.
    • array (optional): The original array the reduceRight() method was called upon.
  • initialValue (optional): An initial starting value for the accumulator.

Basic usage

Let's start with a simple example using both reduce() and reduceRight():

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

const fromLeft = numbers.reduce((accumulator, number) => accumulator + number);
const fromRight = numbers.reduceRight((accumulator, number) => accumulator + number);

console.log(fromLeft);  // Output: 15
console.log(fromRight); // Output: 15

In this example, both methods log the same result of 15 because when simply adding together the order is not important. However, for tasks where order matters, the results would be different.

When order matters

For tasks where the processing order matters, reduceRight() can produce different results than reduce():

const letters = ['a', 'b', 'c', 'd', 'e'];

const fromLeft = letters.reduce((accumulator, letter) => accumulator + letter, '');
const fromRight = letters.reduceRight((accumulator, letter) => accumulator + letter, '');

console.log(fromLeft);  // Output: 'abcde'
console.log(fromRight); // Output: 'edcba'

Using the index parameter

Similar to reduce(), you can use the index parameter to track or list the position in the array:

const colors = ['Red', 'Green', 'Blue', 'Grey', 'Purple'];

const styledColors = colors.reduceRight((html, color, index) => {
  const style =  `background: ${color}; width:100px; height:100px;`;
  return html + `<div style="${style}">Color ${colors.length - index}: ${color}</div>\n`;
});

console.log(styledColors);
// Output:
/* <div style='background: Purple; width:100px; height:100px;'>Color 1: Purple</div>
<div style='background: Grey; width:100px; height:100px;'>Color 2: Grey</div>
<div style='background: Blue; width:100px; height:100px;'>Color 3: Blue</div>
<div style='background: Green; width:100px; height:100px;'>Color 4: Green</div>
<div style='background: Red; width:100px; height:100px;'>Color 5: Red</div> */

Here is the output:

Color 1: Purple
Color 2: Grey
Color 3: Blue
Color 4: Green
Color 5: Red

Using the array parameter

The array parameter gives access to the original array during iteration:

const pizzaLayers = ['Toppings', 'Cheese', 'Sauce', 'Dough'];

const layerDescriptions = pizzaLayers.reduceRight((desc, layer, index, array) => {
  const isFirst = index === array.length - 1;
  const isLast = index === 0;

  if (isFirst) return desc + `Start with ${layer}`;
  if (isLast) return desc + ` and finish with ${layer}.`;

  return desc + `, add ${layer}`;
}, '');

console.log(layerDescriptions);
// Start with Dough, add Sauce, add Cheese and finish with Toppings.

Working with nested structures

The reduceRight() method is useful when flattening nested arrays:

const nestedArray = [[3, 2], [3, 7], [1, 6]];

const flatArray = nestedArray.reduceRight((flattened, current) => {
  return flattened.concat(current);
});

console.log(flatArray);
// Output: [1,6,3,7,3,2]

Practical example: calculating sales per region

This example will store the total sales based on the original array, then calculate the contribution from each region as a percent:

const sales = [10, 89, 180, 125, 210];

const salesReport = sales.reduceRight((report, sale, index, array) => {
  // Calculate total using the original array
  const total = array.reduce((sum, val) => sum + val);
  const percentage = ((sale / total) * 100).toFixed(1);

  const region = array.length - index;
  return report + `Region ${region}: $${sale} (${percentage}% of total)\n`;
}, 'Sales Report:\n');

console.log(salesReport);
/* Output:
Sales Report:
Region 1: $210 (34.2% of total)
Region 2: $125 (20.4% of total)
Region 3: $180 (29.3% of total)
Region 4: $89 (14.5% of total)
Region 5: $10 (1.6% of total)
*/

When to use reduceRight() vs. reduce()

Use reduceRight() when:

  • The order of elements matters and you need to process from right to left.
  • You're building data structures where the right elements need to be processed first.

Use reduce() when:

  • You're performing simple aggregations like averages or sums.
  • The order or the elements does not matter or left-to-right processing is preferred.

Conclusion

The reduceRight() method offers the same capabilities as reduce(), but with the difference of processing elements from right to left.