How Lodash Handles +0 and -0 in Array Intersection
This article examines how the Lodash JavaScript library handles
comparisons between positive zero (+0) and negative zero
(-0) during array intersection operations. Internally,
Lodash delegates array intersections to internal routines that implement
the ECMAScript SameValueZero comparison semantics. As a
result, Lodash treats +0 and -0 as
functionally identical, ensuring consistent matching without
distinguishing between signed zeroes.
The Internal Intersection Pipeline
When calling _.intersection, Lodash routes the call to
an internal function named baseIntersection. This function
determines the common elements across multiple arrays by iterating
through the primary array and verifying the existence of each element in
the remaining arrays.
Depending on the size of the arrays being compared, Lodash employs two different lookup strategies:
- Linear Search: For small arrays, it scans arrays
using internal search helpers (
arrayIncludesorarrayIncludesWith). - Set-Based Caching: For larger arrays, it optimizes
lookups by converting arrays into a
SetCacheinstance to achieve constant-time checks.
Both paths process signed zeroes in an equivalent manner.
Reliance on the
eq Function and Strict Equality
In the linear lookup path, Lodash evaluates element equality using
its internal eq helper. The implementation of
eq is defined as follows:
function eq(value, other) {
return value === other || (value !== value && other !== other);
}In standard JavaScript, the strict equality operator
(===) evaluates +0 === -0 as
true. The secondary condition in eq exists
exclusively to handle NaN comparisons, where
NaN === NaN is otherwise false. Because
+0 === -0 satisfies the first condition immediately, Lodash
treats positive and negative zero as equal matches.
SetCache and
SameValueZero Semantics
For optimized lookups, Lodash wraps arrays inside
SetCache. In modern JavaScript runtimes,
SetCache delegates storage and presence checks directly to
the native ES6 Set object.
Under the ECMAScript specification, the Set collection
uses the SameValueZero algorithm for key comparison:
- Unlike
Object.is(which implementsSameValueand treats+0and-0as distinct),SameValueZerospecifies that+0and-0are equal. - When negative zero (
-0) is added to a nativeSet, it is normalized to positive zero (+0), or treated as already present if+0exists.
Because Lodash relies on these native collection mechanics, negative zero matches positive zero across any intersecting sets handled via caching.
Output Determinism
Because Lodash treats +0 and -0 as
identical during intersection, the signed zero retained in the final
output array depends on whichever signed variant appears first in the
initial (lead) array passed to _.intersection. Lodash does
not mutate or normalize the original zero's sign in the output; it
simply matches the values and preserves the leading reference.