How Lodash _.sample Selects a Random Element
The _.sample method in Lodash provides a reliable way to
retrieve a single pseudo-random element from any JavaScript collection,
including arrays and objects. This article breaks down the internal
execution flow of the _.sample function, detailing how it
normalizes data collections, calculates bounded indices using standard
mathematics, and returns the selected value.
1. Collection Normalization and Length Check
When _.sample(collection) is invoked, Lodash first
checks the type and size of the input. If the provided collection is an
array or array-like object, Lodash directly evaluates its
length property. If the collection is a plain object,
Lodash treats its enumerable property values as the working target
(effectively converting it to an array of values via internal helpers
similar to Object.values).
If the collection is empty, null, or has a length of
zero, the method immediately returns undefined without
executing any random calculations.
2. Random Index Calculation
Once the length n of the collection is established,
Lodash determines an index between 0 and
n - 1. It accomplishes this by calling an internal helper
function, typically named baseRandom.
Under the hood, baseRandom leverages the native
JavaScript Math.random() method. The formula to generate a
uniform integer index within the valid boundary is:
index = Math.floor(Math.random() * length);Because Math.random() produces a floating-point,
pseudo-random number in the range [0, 1) (inclusive of 0,
but exclusive of 1), multiplying it by length results in a
value ranging from 0 up to, but never reaching,
length. Applying Math.floor() rounds down to
the nearest integer, guaranteeing an integer within the exact index
range 0 through length - 1 with an equal
probability for each index.
3. Value Extraction
After generating the random integer, the method accesses the target item:
- For arrays: Lodash accesses the value directly via
bracket notation using the calculated index
(
array[index]). - For objects: Lodash accesses the value at the corresponding position within the converted values array.
The chosen element is then returned directly to the caller. Unlike
sampling algorithms that modify the original structure (such as
destructive shuffling), _.sample performs a non-destructive
read-only operation, leaving the original collection intact.