How Lodash _.without Excludes Array Values
The _.without method in Lodash creates a new array that
excludes all occurrences of specified values from an original array.
This article breaks down how _.without identifies values
for exclusion, the comparison algorithm it uses, and how it handles both
primitive data types and reference types like objects and arrays.
How Values Are Excluded
The _.without method accepts an input array followed by
one or more individual values to be omitted:
_.without(array, [values]);When executed, the method filters out every element in the target array that matches any of the values passed as trailing arguments. It does not mutate the original array; instead, it returns a new, filtered shallow copy.
The Equality Comparison: SameValueZero
Lodash uses the SameValueZero algorithm to determine
whether an array element matches a value marked for exclusion. Under
SameValueZero:
- Primitive values (numbers, strings, booleans,
null,undefined) are excluded when they have identical values and types. NaNvalues are treated as equal. IfNaNis passed to_.without, allNaNentries in the array are removed, which differs from standard JavaScript strict equality (NaN === NaNevaluates tofalse).- Zeroes (
+0and-0) are treated as equal. Excluding0will remove both+0and-0.
Primitives vs. Reference Types
The distinction between primitive values and reference types affects
which values _.without can successfully exclude.
1. Primitive Values
Primitives are compared by value. Any occurrence of that exact value in the array will be removed.
const numbers = [1, 2, 3, 2, 1, 4];
const result = _.without(numbers, 1, 2);
// Output: [3, 4]2. Reference Types (Objects and Arrays)
Objects, arrays, and functions are compared by reference, not by structural or deep equality.
- By Reference: A target object will only be excluded
if the reference passed to
_.withoutpoints to the exact same memory address as the item inside the array. - By Value/Structure: Passing a newly created object with identical properties will fail to exclude the item.
const userA = { id: 1, name: 'Alice' };
const userB = { id: 2, name: 'Bob' };
const users = [userA, userB];
// Excluded because the reference matches:
_.without(users, userA);
// Output: [{ id: 2, name: 'Bob' }]
// Not excluded because the reference is different:
_.without(users, { id: 1, name: 'Alice' });
// Output: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]To exclude objects based on property values or deep equality rather
than reference equality, methods like _.reject or native
Array.prototype.filter with custom predicate functions
should be used instead.