Lodash reduce vs reduceRight Execution Order
In the Lodash JavaScript library, _.reduce and
_.reduceRight are collection functions used to transform an
array or object into a single accumulated result through an iteratee
function. The defining difference between the two lies in their
execution direction: _.reduce iterates through elements
from left to right (from the first element to the last), whereas
_.reduceRight traverses elements from right to left (from
the last element to the first). Because the traversal order is reversed,
non-commutative operations produce entirely different outcomes depending
on which method is used.
Traversal Direction
When working with ordered collections like arrays,
_.reduce begins at index 0 and steps
incrementally to index n - 1. Conversely,
_.reduceRight begins at index n - 1 and moves
backward toward index 0.
Consider string concatenation:
const list = ['a', 'b', 'c', 'd'];
// Left-to-right execution
const leftResult = _.reduce(list, (acc, item) => acc + item, '');
// Result: 'abcd'
// Right-to-left execution
const rightResult = _.reduceRight(list, (acc, item) => acc + item, '');
// Result: 'dcba'In the example above, _.reduce evaluates
'a' first, appending subsequent characters to form
'abcd'. _.reduceRight evaluates
'd' first, then 'c', 'b', and
'a', resulting in 'dcba'.
Impact on Non-Commutative Operations
For commutative operations such as addition or multiplication, the
order of execution does not alter the mathematical outcome (e.g.,
1 + 2 + 3 equals 3 + 2 + 1). However,
operations where order matters—such as division, subtraction, nested
object mutation, or string formatting—will yield different results.
const numbers = [2, 4, 8];
// Left-to-right: ((2 / 4) / 8) = 0.0625
const divisionLeft = _.reduce(numbers, (acc, num) => acc / num);
// Right-to-left: ((8 / 4) / 2) = 1
const divisionRight = _.reduceRight(numbers, (acc, num) => acc / num);Accumulator Defaults
When an initial accumulator value is omitted:
_.reduceuses the first element of the collection (index0) as the initial accumulator and begins execution with the second element (index1)._.reduceRightuses the last element of the collection (indexn - 1) as the initial accumulator and begins execution with the second-to-last element (indexn - 2).
Functional Composition Use Cases
_.reduceRight is commonly used in functional programming
patterns, particularly for standard mathematical function composition
(often referred to as compose), where functions are applied
to an argument from right to left (innermost to outermost). In contrast,
_.reduce forms the foundation of function piping
(pipe or flow), where functions are applied
sequentially from left to right.
const addFive = (x) => x + 5;
const double = (x) => x * 2;
const pipeline = [addFive, double];
// Pipe (reduce): double(addFive(10)) => (10 + 5) * 2 = 30
const piped = _.reduce(pipeline, (val, fn) => fn(val), 10);
// Compose (reduceRight): addFive(double(10)) => (10 * 2) + 5 = 25
const composed = _.reduceRight(pipeline, (val, fn) => fn(val), 10);Handling Objects
When applied to objects rather than arrays, _.reduce
iterates through the object's own enumerable string keyed properties in
standard JavaScript property order. _.reduceRight iterates
through these same keys in reverse order.