Lodash orderBy Sort Stability Explained

Lodash's _.orderBy provides a guaranteed stable sort when processing collections in JavaScript. When multiple elements produce identical values across all specified sorting criteria, Lodash preserves their original relative order from the input array. This article explains how _.orderBy handles complete ties, the mechanism behind its stability guarantee, and how it impacts predictable data sorting.

The Stability Guarantee

A sorting algorithm is considered stable if it preserves the original relative order of elements with equal sorting keys. When using Lodash's _.orderBy(collection, [iteratees=[_.identity]], [orders]), the function evaluates elements sequentially across the provided iteratees.

If two or more items have identical values for the first sorting criteria, the algorithm moves to the second criteria, and so forth. If two elements tie across every specified iteratee and corresponding sort order, _.orderBy guarantees stability by retaining the sequence in which those elements initially appeared in the source array.

How Lodash Resolves Ties

Internally, Lodash maps the original collection into intermediate objects that pair each element with its computed sorting criteria and its original index in the source array. This technique is often referred to as a Schwartzian transform.

During the comparison phase:

  1. Lodash evaluates the criteria from left to right according to the directions specified in orders ('asc' or 'desc').
  2. If all user-defined criteria produce an exact match (a tie), Lodash uses the element's original index as the final tiebreaker.
  3. The original index is always evaluated in ascending order, ensuring that whichever tied item appeared first in the input collection appears first in the final output.

Practical Example of an Exact Tie

Consider the following collection sorted by role and age:

const users = [
  { id: 1, name: 'Alice', role: 'admin', age: 30 },
  { id: 2, name: 'Bob', role: 'user', age: 25 },
  { id: 3, name: 'Charlie', role: 'admin', age: 30 },
  { id: 4, name: 'Diana', role: 'user', age: 25 }
];

const result = _.orderBy(users, ['role', 'age'], ['asc', 'desc']);

In this scenario:

Because all specified sorting criteria evaluate to the same values for these pairs, the exact tie fallback activates. Alice (index 0) is guaranteed to precede Charlie (index 2), and Bob (index 1) is guaranteed to precede Diana (index 3) in the resulting array.

Independent of Runtime Quirks

While ECMAScript 2019 (ES10) mandated that the native Array.prototype.sort must be stable, earlier JavaScript engine implementations did not guarantee stability for large arrays. Lodash’s internal index-tracking mechanism ensures that _.orderBy remains deterministic and stable across all JavaScript runtimes, environments, and array sizes without relying on native sorting quirks.