Lodash intersection and ES6 Symbol Values
Lodash’s _.intersection method computes the set of
shared elements across multiple arrays using the SameValueZero equality
comparison algorithm. When applied to arrays containing ECMAScript 2015
(ES6) Symbol values, _.intersection handles
them strictly according to standard JavaScript reference identity. This
article explains how _.intersection evaluates local versus
global symbols, how Lodash's internal caching accommodates symbol
primitives, and what to expect when intersecting arrays with symbol
data.
SameValueZero Comparison and Reference Identity
The _.intersection function determines whether an
element from the first array exists in all subsequent arrays by
utilizing Lodash's internal comparator based on the SameValueZero
specification. Because Symbol is a primitive type designed
to be unique and immutable, equality is determined strictly by reference
identity:
- Matching References: If the exact same
Symbolreference is present across all provided arrays,_.intersectionrecognizes the match and retains the symbol in the output array. - Distinct Symbols with Identical Descriptions:
Calling
Symbol('desc')creates a completely unique primitive every time. Even if two symbols in separate arrays share the exact same description, they are not equal (Symbol('desc') !== Symbol('desc')). Consequently, they will not be treated as matching values and will be excluded from the intersection result.
const sharedSymbol = Symbol('shared');
const array1 = [sharedSymbol, Symbol('unique'), 'apple'];
const array2 = [sharedSymbol, Symbol('unique'), 'banana'];
_.intersection(array1, array2);
// Output: [sharedSymbol]Global Symbols via
Symbol.for()
When symbols are registered using the runtime's global symbol
registry via Symbol.for(key), the registry returns the same
symbol reference for identical keys across different parts of the code.
Because Symbol.for('key') === Symbol.for('key'),
_.intersection will successfully identify these values as
identical across multiple arrays:
const listA = [Symbol.for('token'), 10];
const listB = [Symbol.for('token'), 20];
_.intersection(listA, listB);
// Output: [Symbol(token)]Internal Caching and Map/Set Compatibility
For performance optimization when dealing with larger arrays, Lodash
constructs internal lookup structures such as SetCache and
MapCache. In modern JavaScript engines, native
Set and Map structures natively support
Symbol primitives as distinct keys.
Older manual object hashing techniques that coerce keys to
strings—such as using an element as a plain object property key
(cache[key] = true)—would throw a runtime
TypeError: Cannot convert a Symbol value to a string.
Lodash's implementation avoids this error by delegating lookups to
modern native collections or guarded key-retrieval mechanisms that
preserve Symbol identity without coercion.
Output Order and Uniqueness
When Symbol values are included in the result:
- Ordering: Matches maintain the order of their first
appearance in the primary (first) array passed to
_.intersection. - Uniqueness: The resulting array contains no duplicate symbols, even if the primary array contains multiple references to the same symbol.