Pull / PullAllLoading saved progress…

Pull / PullAll

pull and pullAll remove every occurrence of the given values from an array by mutating it in place, and return that same array — not a copy. They are the mutating counterparts of set-difference helpers like difference: instead of building a new array of what is left, they reach into the array you passed and delete the matches, so any variable still holding that array sees the change. This is lodash's _.pull and _.pullAll.

Implement both, packaged on one object named `{ pull, pullAll }`. pull is variadic (the values come as extra arguments); pullAll takes the values as a single array. pull should delegate to pullAll.

Signature

pullValues = { pull, pullAll }

// remove every value from `array` IN PLACE, then return that same array:
pull(array, ...values)   // values as extra args:  pull(arr, 2, 3)
pullAll(array, values)   // values as one array:   pullAll(arr, [2, 3])

Examples

pull([1, 2, 3, 1, 2, 3], 2, 3);
// → [1, 1]   the return value IS the same array, now mutated

pullAll([1, 2, 3, 1, 2, 3], [2, 3]);
// → [1, 1]   pullAll takes the values as one array
pull([2, 2, 2, 1], 2);     // → [1]   every copy gone, even adjacent ones
pull([NaN, 1, NaN], NaN);  // → [1]   NaN matches NaN
pull([1, 2, 3], 9);        // → [1, 2, 3]   nothing to remove: unchanged

Notes

  • Mutate in place — change the array you were given and return it; the returned array must be the same reference, so pull(a, x) === a is true. Do not allocate or return a new array.
  • Remove every occurrence — not just the first match, and including runs of adjacent duplicates.
  • Order is preserved — the surviving elements keep their original relative order.
  • Match with SameValueZero — the equality Array.prototype.includes and Set use, where NaN matches NaN and -0 matches 0. (Plain indexOf and === would miss NaN.)
  • No values is a no-oppull(a) and pullAll(a, []) return a unchanged, still the same reference.
  • Do not use _.pull — build the behavior yourself; the point is the in-place removal, not the library call.

FAQ

Do pull and pullAll mutate the array or return a new one?
They mutate the array in place and return that same array reference. This is the opposite of difference and without, which allocate and return a brand-new array and leave the original untouched.
Why does splicing inside a forward loop miss some values?
When you splice out index i, every later element shifts one slot to the left, so the element that was at i+1 now sits at i. The loop then advances to i+1 and skips it. Adjacent duplicates are exactly the case that survives. A write-index compaction avoids this.
How are values matched — does NaN work?
Matching uses SameValueZero, the same equality Array.prototype.includes and Set use, so NaN matches NaN and -0 matches 0. Using indexOf instead would rely on strict equality, where NaN never equals NaN, and every NaN would survive.
Loading editor…