Lodash intersectionBy with Undefined Iteratee
When the iteratee function provided to Lodash's
_.intersectionBy returns undefined for every
element, the method collapses all elements into a single shared
comparison key. Assuming all provided arrays contain at least one
element, _.intersectionBy treats every element across all
arrays as equivalent and returns an array containing exclusively the
first element of the first array. If any provided array is completely
empty, the method returns an empty array.
How Lodash Evaluates the Iteratee
The _.intersectionBy method computes the intersection of
multiple arrays based on a criterion generated by invoking an iteratee
for each element. The values in the resulting array are drawn directly
from the first array, while subsequent arrays dictate which criteria are
preserved.
Internally, Lodash generates mapped criteria sets for comparison:
- Each element in the primary array is mapped to a criterion using the iteratee.
- Each element in the secondary arrays is similarly mapped to build lookup sets.
- Elements from the first array are retained only if their computed criterion exists within all secondary arrays.
- Duplicate criteria are discarded to ensure the resulting array contains unique matches based on the criterion.
Why the Result Contains Only the First Element
When the iteratee explicitly or implicitly returns
undefined for every element:
- Criterion Homogeneity: Every element in every array
produces the identical criterion:
undefined. - Intersection Match: Lodash checks whether the first
element of the first array (whose criterion is
undefined) exists in the criteria of all other arrays. Because the other arrays also map toundefined, a match is confirmed. - Deduplication: Lodash maintains a cache of
already-matched criteria to prevent duplicate elements in the
intersection. Once the criterion
undefinedis added to this cache via the first element, every subsequent element in the first array—which also maps toundefined—is flagged as a duplicate and ignored.
Consequently, only the very first element of the first array passes into the final result.
Example Behavior
const _ = require('lodash');
const array1 = ['apple', 'banana', 'cherry'];
const array2 = ['orange', 'grape'];
const array3 = ['melon'];
// Iteratee returns undefined for every element
const result = _.intersectionBy(array1, array2, array3, () => undefined);
console.log(result);
// Output: ['apple']In the event that any array passed to the method is empty:
const emptyArray = [];
const resultWithEmpty = _.intersectionBy(array1, emptyArray, () => undefined);
console.log(resultWithEmpty);
// Output: []Because emptyArray contains no elements, the criterion
undefined is never produced for that array, meaning no
common criterion exists across all inputs.