Lodash reduceRight Object vs Array Traversal

Lodash’s _.reduceRight method executes a reducer function over a collection from right to left, but its traversal mechanism differs fundamentally between arrays and plain objects. While arrays are stepped through sequentially from the highest numeric index down to zero, objects are evaluated by first determining their enumerable own keys and iterating through that key set in reverse order. Understanding this distinction is critical for predicting accumulator values, handling non-sequential property orders, and avoiding subtle bugs during data transformations.

Array Traversal: Index-Based Decrementing

When supplied with an array, _.reduceRight relies on the collection's indexed structure:

For example, given [1, 2, 3], the iteratee processes the element 3 (index 2), then 2 (index 1), and finally 1 (index 0).

Object Traversal: Key Extraction and Reversal

JavaScript objects do not have native backward iteration, nor are their properties stored in a strictly linear manner. When _.reduceRight receives an object, it handles traversal through a multi-step process:

  1. Key Resolution: Lodash retrieves the object's own enumerable properties, adhering to the ECMAScript specification for property order:
    • Non-negative integer-like keys are sorted in ascending numerical order.
    • String keys are listed in the order they were inserted.
    • Symbol keys are handled separately (or omitted by default object key iterators).
  2. Reverse Iteration: Lodash iterates through this resolved list of property keys from the last key to the first.
  3. Callback Arguments: The iteratee receives (accumulator, value, key, collection).

Because keys must be gathered before iteration begins, reducing an object carries the memory and computational overhead of creating this intermediate key list.

Key Traversal Differences

Feature Array Traversal Object Traversal
Iteration Mechanism Decrementing integer counter Reverse iteration over resolved key list
Position Identifier Numeric index (0 to n - 1) String property name
Order Determinism Strictly strictly reverse index order Dependent on ECMAScript key sorting rules
Intermediate Allocation No key array allocation required Allocates a list of property keys first

The Impact of Numeric Object Keys

A common pitfall occurs when objects use numeric strings as keys. Because ECMAScript sorts integer keys in ascending order prior to standard string keys, _.reduceRight will always visit the highest integer key first among the integer keys, regardless of insertion order:

const obj = {
  'b': 'second_string',
  '1': 'first_number',
  '2': 'second_number',
  'a': 'first_string'
};

In this case, Lodash resolves the keys in the order ['1', '2', 'b', 'a']. Consequently, _.reduceRight traverses them in reverse: 'a', then 'b', then '2', and finally '1'.

Arrays, by contrast, follow strict, contiguous numerical boundaries where elements are always consumed strictly from right to left as defined by array positioning.