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:

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.