Lodash _.union Behavior with Mixed Primitives
This article examines how the Lodash JavaScript library handles mixed
primitive types when passed into the _.union function. It
explains the internal unpacking mechanism, focusing on how Lodash
flattens arguments, evaluates values against the
isArrayLikeObject predicate, and filters or retains
primitive types during execution.
The Internal Flattening Mechanism
Lodash defines _.union to accept multiple arrays via
rest parameters, which it then processes using an internal flattening
utility (baseFlatten). Specifically, _.union
applies a shallow flattening step with a depth of 1 and
evaluates candidates using the isArrayLikeObject validation
predicate.
function union(...arrays) {
return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
}This predicate dictates entirely how _.union unpacks its
arguments.
Direct Primitive Arguments Are Ignored
When mixed primitive values (such as numbers, strings, booleans,
null, or undefined) are passed directly as
arguments to _.union, they are not unpacked into the final
array; they are completely discarded.
Lodash’s isArrayLikeObject helper requires a value to
satisfy two conditions:
- It must be an object-like value
(
typeof value === 'object' && value !== null). - It must be array-like (has a valid integer
lengthproperty between0andNumber.MAX_SAFE_INTEGER).
Because primitive values fail the isObjectLike check,
they do not qualify:
- Numbers, Booleans, Symbols,
null, andundefined: These fail both checks and are skipped. - Strings: Although primitive strings have indexed
characters and a
.lengthproperty, they fail theisObjectLikecheck (typeof "str" !== 'object'). Consequently, strings passed directly as arguments are excluded rather than unpacked character-by-character.
// Example: Direct primitives passed as arguments
_.union([1, 2], 3, "hello", null, true);
// Output: [1, 2]Primitives Contained Within Arrays
When mixed primitives are contained inside the array
arguments passed to _.union, the unpacking behavior is
different:
- One-Level Unpacking: The outer arrays satisfy
isArrayLikeObjectand are unwrapped by exactly one level. - Preservation of Elements: The individual elements
within those arrays—regardless of whether they are numbers, strings,
booleans, objects,
null, orundefined—are extracted into a single combined collection. - Deduplication via SameValueZero: Lodash passes the
flattened collection to
baseUniq, which uses theSameValueZerocomparison algorithm. This ensures that:- Primitives of identical type and value are deduplicated
(
'a' === 'a'). NaNvalues are considered equal to one another and deduplicated.+0and-0are treated as equivalent.
- Primitives of identical type and value are deduplicated
(
// Example: Arrays containing mixed primitives
_.union([1, 'a', null, NaN], [2, 'a', undefined, NaN]);
// Output: [1, 'a', null, NaN, 2, undefined]In summary, _.union only unpacks arguments that pass
isArrayLikeObject. Direct primitive arguments are ignored,
while primitives enclosed inside arrays are extracted during the
single-level flatten and deduplicated using
SameValueZero.