Lodash _.differenceWith() method
What you’ll learn
- How
_.differenceWith(array, ...values, comparator)drops items when your comparator says they match any exclusion value. - Pairing
differenceWithwith_.isEqualfor deep structural compares. - When to stay with
_.differenceByfor a single projection versus a full comparator. - Try each example in the editor (
?tryit=1,2,3) with Lodash from a CDN.
Prerequisites
Read _.difference() and _.differenceBy() on this site first.
- You can write a pure predicate
(a, b) => booleanwithout mutatingaorb. - You can run snippets in Node or open the Try-it labs in a browser.
Overview
_.differenceWith filters the first array like difference, but two values count as the same whenever your comparator returns truthy. That unlocks deep equality, numeric tolerances, or multi-field rules that do not fit a single iteratee projection.
Deep equality
Pass _.isEqual (or similar) so different object instances with the same shape are excluded.
Custom rules
Encode tolerances, case-insensitive strings, or domain-specific “same record” logic in one function.
Non-destructive
Inputs are read-only; the result is a new array of references from the first array.
Syntax
_.differenceWith(array, [values], comparator) - array: source collection to filter.
- values: zero or more arrays (each flattened one level) whose elements act as exclusion candidates.
- comparator:
(arrVal, othVal) => boolean— return a truthy value when the two should be treated as equal for removal. - Returns: a new array of elements from
arraythat do not comparator-match any flattened exclusion value.
Deep equality with isEqual
Different object references with the same nested shape are removed when you pass Lodash isEqual as the comparator.
import differenceWith from "lodash/differenceWith";
import isEqual from "lodash/isEqual";
differenceWith(
[{ x: 1, y: 2 }, { x: 2, y: 1 }],
[{ x: 1, y: 2 }],
isEqual
);
// [{ x: 2, y: 1 }] Numeric tolerance
Treat two numbers as the same when their absolute difference is within a small epsilon.
import differenceWith from "lodash/differenceWith";
differenceWith([1.0, 2.5, 3.1], [1.05], (a, b) => Math.abs(a - b) < 0.2);
// [2.5, 3.1] Several exclusion lists
Later arrays are flattened one level and unioned; the same comparator applies to every pair check.
import differenceWith from "lodash/differenceWith";
differenceWith(
[{ id: 1 }, { id: 2 }, { id: 3 }],
[{ id: 2 }],
[{ id: 3 }],
(a, b) => a.id === b.id
);
// [{ id: 1 }] 📋 differenceWith vs differenceBy
| Method | How equality is decided | Typical use |
|---|---|---|
_.differenceBy | SameValueZero on iteratee(value) | One stable key or projection per value |
_.differenceWith | Your comparator on the raw pair (arrVal, othVal) | Deep structures, tolerances, or multi-field logic |
Pitfalls to avoid
Quadratic comparisons
Each survivor is checked against every exclusion value. Huge lists may need hashing or mapping to IDs first instead of a heavy comparator.
Asymmetric comparators
Lodash will call your function with (candidate, exclusion) in that order; keep the predicate consistent so the same logical pair always matches regardless of argument order if you reuse the function elsewhere.
Loose truthy returns
Return a strict boolean when possible. Accidentally returning a non-zero number can look like a match and hide bugs.
❓ FAQ
Summary
- Purpose:
_.differenceWith(array, ...values, comparator)filters the first array using your comparator instead of reference or SameValueZero checks alone. - Safety: inputs are not mutated.
- Next: Lodash _.drop(), _.drop(), or the array methods hub.
Return true from the comparator when the two values should be treated as a match for removal. Lodash pairs each candidate from the first array against exclusion values using that predicate; order of the first array is preserved among survivors.
6 people found this page helpful
