Array.prototype.reduceRight()
reduceRight(callbackFn, initialValue) The reduceRight() method applies a callback function against an accumulator and each element in the array (from right to left) to reduce it to a single value.
Syntax
reduceRight(callbackFn)
reduceRight(callbackFn, initialValue)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
callbackFn | Function | — | Function to execute for each element. Receives accumulator, currentValue, currentIndex, and array. |
accumulator | any | — | Value accumulated across iterations. First call uses initialValue if provided, otherwise array[last]. |
currentValue | any | — | Value of current element. |
currentIndex | number | — | Index of current element. |
array | Array | — | The array being reduced. |
initialValue | any | undefined | Starting value for accumulator. |
Examples
Flattening nested arrays
const nested = [[1, 2], [3, 4], [5, 6]];
const flat = nested.reduceRight((acc, curr) => acc.concat(curr), []);
console.log(flat); // [5, 6, 3, 4, 1, 2]
Compare with reduce() which would produce [1, 2, 3, 4, 5, 6]. The order of the flattened result differs because reduceRight visits elements from the last index to the first, so the rightmost sub-array appears first in the output. For operations where the accumulator order does not matter — like summing numbers — reduce and reduceRight produce the same result. But when the combination order affects the outcome, the direction matters.
Difference between reduce and reduceRight
// reduce processes left to right
[1, 2, 3].reduce((acc, x) => [...acc, x * 2], []);
// Result: [2, 4, 6]
// reduceRight processes right to left
[1, 2, 3].reduceRight((acc, x) => [...acc, x * 2], []);
// Result: [6, 4, 2]
The doubling example makes the direction visible: left-to-right doubles 1 first ([2]), then 2 ([2, 4]), then 3 ([2, 4, 6]); right-to-left doubles 3 first ([6]), then 2 ([6, 4]), then 1 ([6, 4, 2]). The same pattern applies to any operation where the accumulator is built incrementally. When the callback is not commutative — like subtraction or division — the direction changes the numerical result, not just the element order.
Common Patterns
Right-associative operations: When the operation is not commutative, like subtraction or division.
// Subtraction with reduce (left to right)
[10, 5, 2].reduce((a, b) => a - b); // (10 - 5) - 2 = 3
// Subtraction with reduceRight (right to left)
[10, 5, 2].reduceRight((a, b) => a - b); // (10 - (5 - 2)) = 7
When to Use reduceRight
Use reduceRight() when:
- The operation is not commutative (subtraction, division)
- You need to process from right to left
- You’re working with nested structures where order matters
Parameters
| Parameter | Type | Description |
|---|---|---|
callbackFn | function | Called with (accumulator, currentValue, currentIndex, array) for each element, right to left. |
initialValue | any | Optional starting value for the accumulator. If omitted, the last element is used and iteration starts from the second-to-last. |
How reduceRight() works
reduceRight() iterates from the last element (index array.length - 1) down to index 0. At each step, it calls callbackFn(accumulator, currentValue, currentIndex, array) and uses the return value as the new accumulator. When initialValue is provided, the first call receives initialValue as the accumulator and the last element as currentValue. Without initialValue, the last element becomes the initial accumulator and iteration starts at the second-to-last element.
Initial value
When initialValue is provided, the first call to the callback receives initialValue as the accumulator and the last array element as currentValue. When omitted, the first call uses the last element as the accumulator and the second-to-last as currentValue. Always provide an initialValue for clarity and to avoid a TypeError on empty arrays.
// Without initialValue: TypeError on empty array
[].reduceRight((acc, x) => acc + x); // TypeError
// With initialValue: safe on empty array
[].reduceRight((acc, x) => acc + x, 0); // 0
Providing an initial value also makes the accumulator type predictable — without it, the accumulator inherits the type of the last element, which can surprise you when the array contains mixed types. Once you have a handle on the basic reduction pattern, reduceRight reveals its most elegant use case: composing functions in the order they read, from right to left, matching the mathematical convention.
Function composition
reduceRight is classically used to compose functions in right-to-left order — the mathematical convention for function composition, where (f ∘ g)(x) = f(g(x)):
const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
const double = x => x * 2;
const addOne = x => x + 1;
const square = x => x * x;
const transform = compose(double, addOne, square); // double(addOne(square(x)))
console.log(transform(3)); // double(addOne(9)) = double(10) = 20
reduceRight() vs reduce() + reverse()
[...arr].reverse().reduce(fn) produces the same result as arr.reduceRight(fn) for symmetric accumulations, but reduceRight is preferred: it does not allocate a reversed copy of the array and communicates the right-to-left intent directly.
Why reduceRight() Exists
reduceRight() is the right tool when the order of combination matters, especially for nested expressions or right-associative operations. It keeps the original array intact and avoids the extra reverse step that older patterns needed. That makes the intent easier to read and the implementation easier to maintain. If the order does not matter, reduce() is usually simpler; if the order does matter, reduceRight() makes that dependency explicit.
See Also
- Array.prototype.map() — Transform each element
- Array.prototype.filter() — Select elements by condition