Lodash _.pullAllWith() method
What you’ll learn
- How
_.pullAllWith(array, values, comparator)deletes elements whencomparator(arrVal, othVal)is truthy for anyothValinvalues. - Why this generalizes _.pullAllBy() when pairwise logic beats a single projection.
- How to pair the helper with
_.isEqualfor nested structures and when to clone first. - Try each example in the editor (
?tryit=1,2,3) with Lodash from a CDN.
Prerequisites
Read _.pullAllBy() and _.intersectionWith() for comparator conventions; optional _.differenceWith() for non-mutating subtraction.
- You understand that in-place array helpers affect every reference to that array.
- You can run snippets in Node or open the Try-it labs in a browser.
Overview
_.pullAllWith is the comparator-driven removal tool in the pull family. Lodash asks your function to decide whether an element from the target array “matches” any ban entry; truthy answers drop the element, while the array reference itself is preserved for chaining.
Pairwise control
Compare arrVal and othVal directly instead of projecting through one iteratee.
In place
The first array is mutated; the return value is the same reference.
Deep equals
Reuse _.isEqual when nested shapes must match, not just top-level references.
Syntax
_.pullAllWith(array, values, [comparator]) - array: collection to mutate.
- values: array of exclusion candidates compared against each element of
array. - comparator: optional
(arrVal, othVal) => boolean; truthy means treat the pair as equal for removal. - Returns: the same
arrayreference after removals.
Deep equality with _.isEqual
A fresh object literal in values can still match a row when the comparator performs a structural compare.
import pullAllWith from "lodash/pullAllWith";
import isEqual from "lodash/isEqual";
const rows = [
{ a: 1, b: { c: 2 } },
{ a: 9 }
];
pullAllWith(rows, [{ a: 1, b: { c: 2 } }], isEqual);
// rows is now [{ a: 9 }] Numeric tolerance
Custom comparators can express ranges—for example removing every reading near a calibration anchor.
import pullAllWith from "lodash/pullAllWith";
const readings = [{ v: 10.1 }, { v: 10.0 }, { v: 20 }];
pullAllWith(readings, [{ v: 10 }], (a, b) => Math.abs(a.v - b.v) < 0.11);
// readings is now [{ v: 20 }] Multi-field match
When only a subset of fields matters, compare them explicitly inside the comparator.
import pullAllWith from "lodash/pullAllWith";
const events = [
{ type: "click", target: "btn-a" },
{ type: "scroll", target: "main" },
{ type: "click", target: "btn-b" }
];
pullAllWith(events, [{ type: "click", target: "btn-a" }], (a, b) =>
a.type === b.type && a.target === b.target
);
// events is now [{ type: "scroll", target: "main" }, { type: "click", target: "btn-b" }] 📋 _.pullAllWith vs _.pullAllBy vs _.differenceWith
| API | Mutation | Note |
|---|---|---|
_.pullAllWith(array, values, comparator) | Mutates array | Pairwise comparator decides matches |
_.pullAllBy(array, values, iteratee) | Mutates array | Single projection per side, SameValueZero on results |
_.differenceWith(array, values, comparator) | Returns a new array | Non-destructive subtraction of exclusions |
Pitfalls to avoid
Asymmetric comparators
Lodash may invoke (arrVal, othVal) in either order depending on internal pairing; keep comparisons logically symmetric when possible.
O(n×m) scans
Each element is checked against every ban entry; huge ban lists can get expensive compared to keyed lookups.
Undo buffers
Clone before pulling when you need snapshots for rollback or auditing.
❓ FAQ
Summary
- Purpose:
_.pullAllWith(array, values, comparator)removes elements whose comparator reports a match against any value invalues. - Mutation: the first array is updated in place; clone first when isolation matters.
- Next: Lodash _.pullAt(), _.pullAllBy() (previous), or the array methods hub.
The comparator receives (arrVal, othVal)—the same pairing style as _.differenceWith() and _.intersectionWith(), except pullAllWith mutates the first array instead of allocating a new result.
6 people found this page helpful
