How Lodash union Handles Mixed Primitives
This article examines how the Lodash JavaScript library's
_.union function processes arrays containing mixed
primitive data types such as numbers, strings, booleans,
null, and undefined. It breaks down the
internal equality comparison mechanism used by the utility, demonstrates
how the function avoids type coercion, and provides clear examples of
how diverse primitive types are preserved, ordered, and
deduplicated.
The Equality Mechanism: SameValueZero
Lodash's _.union creates an array of unique values, in
order, from all given arrays. When comparing items across arrays to
determine uniqueness, Lodash relies internally on the ECMAScript
SameValueZero comparison algorithm.
Because SameValueZero performs strict type evaluation
without type coercion, _.union treats values of different
primitive types as fundamentally distinct, even if they would evaluate
to equal under loose equality (==).
Handling Different Primitive Types
When processing mixed primitives, _.union adheres to the
following rules:
- Numbers vs. Strings: Values such as
1and'1'are treated as separate, unique entities. Neither is coerced to match the other. - Booleans vs. Falsy/Truthy Values: A boolean
falseis not considered equal to0,"",null, orundefined. Similarly,trueis distinct from1. - Null and Undefined: Both
nullandundefinedare treated as separate primitive types. Multiple instances ofnullcollapse into a singlenull, and multiple instances ofundefinedcollapse into a singleundefined, but they never merge with each other. - NaN Values: Unlike strict equality
(
===), which evaluatesNaN === NaNasfalse,SameValueZerotreatsNaNas equal toNaN. Consequently, multipleNaNvalues across input arrays are deduplicated into a singleNaN. - Symbols and BigInts: Modern primitives such as
SymbolandBigIntare also compared strictly. ABigInt(1)is distinct from the number1or the string'1'. Distinct symbol instances remain separate, while references to the exact same symbol are deduplicated.
Ordering and Deduplication
The order of the resulting array is determined by the order in which items first appear across the provided arrays. The first occurrence of any unique primitive is retained, and all subsequent duplicates—regardless of which array they appear in—are discarded.
Code Example
The following code illustrates how _.union resolves an
array containing mixed primitives:
const _ = require('lodash');
const array1 = [1, '1', false, null, NaN];
const array2 = ['1', 0, false, undefined, NaN, null];
const result = _.union(array1, array2);
console.log(result);
// Output: [ 1, '1', false, null, NaN, 0, undefined ]In this output:
1and'1'both remain because their data types differ.falseand0remain distinct.- The duplicate occurrences of
'1',false,null, andNaNfromarray2are removed. - The elements are returned in the exact order they were first encountered across the input arrays.