How Lodash minBy Handles and Bypasses NaN
This article examines the internal algorithmic path utilized by the
Lodash JavaScript library's _.minBy function to skip and
bypass NaN values during collection traversal. By analyzing
the underlying baseExtremum helper and Lodash's comparison
strategy, this guide demonstrates how both leading and trailing
NaN values are systematically excluded without terminating
iteration or corrupting the computed minimum.
The Underlying Architecture: baseExtremum
In Lodash, _.minBy acts as a wrapper that passes the
target collection, the iteratee function, and a comparison function
(baseLt) to an internal function named
baseExtremum.
The simplified core loop of baseExtremum operates as
follows:
function baseExtremum(array, iteratee, comparator) {
var index = -1,
length = array == null ? 0 : array.length,
result,
computed;
while (++index < length) {
var value = array[index],
current = iteratee(value);
if (current != null && (computed === undefined
? (current === current && !isSymbol(current))
: comparator(current, computed)
)) {
computed = current;
result = value;
}
}
return result;
}To bypass strictly NaN values, the algorithmic path
branches into two distinct phases: establishing the initial baseline and
evaluating subsequent elements.
Phase 1: Bypassing Leading NaN Values via Self-Equality
Before any valid candidate is found, the internal tracking variable
computed remains undefined. During these
iterations, the algorithm enters the first branch of the ternary
condition:
current === current && !isSymbol(current)In JavaScript, NaN is the only primitive value that is
not equal to itself (NaN === NaN evaluates to
false).
When iteratee(value) returns NaN:
- The condition
current != nullevaluates totrue(sinceNaNis neithernullnorundefined). - Because
computedis stillundefined, the ternary operator evaluatescurrent === current. - Because
NaN === NaNisfalse, the entireifstatement evaluates tofalse. - The assignment is skipped, leaving
computedandresultasundefined.
The loop proceeds to the next element without setting
NaN as the current minimum candidate.
Phase 2: Bypassing Subsequent NaN Values via baseLt
Once an element yields a valid, non-NaN value,
computed is assigned that value and is no longer
undefined. For all subsequent iterations, the algorithm
diverts to the second branch of the ternary operator, executing the
comparator:
comparator(current, computed)For _.minBy, the comparator is baseLt,
which performs a standard less-than comparison:
function baseLt(value, other) {
return value < other;
}According to IEEE 754 floating-point specifications implemented in
JavaScript, any relational comparison involving NaN
evaluates to false:
NaN < computedis alwaysfalse.computed < NaNis alwaysfalse.
When an iteration encounters an element where
iteratee(value) produces NaN:
baseLt(NaN, computed)is invoked.- The comparison returns
false. - The
ifcheck fails, ensuring thecomputedminimum and the correspondingresultreference remain untouched.
Complete Traversal Outcome
Through this dual-stage mechanism, _.minBy achieves a
clean algorithmic bypass:
- Initial/Leading
NaNs are discarded by failing thecurrent === currentidentity test, preservingcomputedin an unset state until a valid value appears. - Subsequent
NaNs are discarded becausebaseLtcomparisons againstNaNreturnfalse, preventingNaNfrom overriding an established minimum.
If an entire array consists exclusively of values resolving to
NaN (or null/undefined),
computed remains undefined throughout the
lifecycle of the loop, and _.minBy safely returns
undefined.