Set.prototype.delete()

Removes a value and reports whether it was actually there to remove.

Signature
delete(value)
  • Added in JavaScript ES2015

Parameters

ParameterTypeDescription
$valueanyThe value to remove. Compared with SameValueZero; objects are matched by reference, not by their contents.

Return value

booleantrue if a value was present and has been removed, false if it was not found.

Errors

Throws a TypeError if called on a value that is not a real Set instance. Removing a missing value is not an error.

delete() removes one value and returns a boolean saying whether anything was there. That return value is genuinely useful — it is an atomic test-and-remove, so if (s.delete(x)) { ... } saves you a separate has() call. It contrasts with add(), which tells you nothing.

Removing a value that is not in the collection is a no-op, not an error. There is no bulk form: to remove several values, loop, or build a new collection with difference().

Deleting while iterating

Unlike splicing an array inside its own loop, deleting from a Set during for...of or forEach() is well defined and safe. Entries already visited stay visited; an entry deleted before the iterator reaches it is simply never yielded. This makes the "iterate and remove what matches" pattern legitimate here.

One caveat: a value that is deleted and then re-added during the same iteration will be visited again, because it is re-appended at the end.

Objects

You can only delete an object you hold a reference to. If the reference has been lost, the entry is unreachable through delete() and you have to find it by iterating. Also note that a plain Set keeps its objects alive — use a WeakSet when you want them collectable.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Release a lock or in-flight request id once its work finishes
  • Remove a tag when the user unclicks it in a filter UI
  • Prune every stored object whose coordinates fall outside a viewport
  • Test-and-remove a one-time token in a single expression

Frequently asked questions

What does Set delete() return?

A boolean: true when the value was present and has now been removed, false when it was not found. That makes it an atomic test-and-remove, so a separate has() check is unnecessary.

Is it safe to delete from a Set while iterating it?

Yes — deleting during for...of or forEach() is well defined, and an entry removed before the iterator reaches it is simply skipped. The one exception is a value deleted and re-added mid-loop, which gets visited again at the end.

How do I delete multiple values from a Set?

There is no bulk delete, so loop over the values you want gone and call delete() on each. To get a new collection instead of mutating the original, use difference().

More examples

Test and remove in one step

The boolean return makes a duplicate completion callback harmless and detectable without a preceding has() call. Only the first settle for req-1 reports success; the rest fall through to the unknown branch.

Example · javascript
const pendingRequests = new Set(["req-1", "req-2"]);

function settle(id) {
  if (pendingRequests.delete(id)) {
    console.log(`settled ${id}`);
  } else {
    console.log(`unknown or already settled: ${id}`);
  }
}

settle("req-1");
settle("req-1");
settle("req-9");
console.log([...pendingRequests]);

Delete then re-add during iteration

Removing "a" and immediately re-adding it appends it to the end, so the same loop visits it a second time and visits is ["a","b","c","a"]. This is the one case where an iteration is not guaranteed to see each value exactly once.

Example · javascript
const s = new Set(["a", "b", "c"]);
const visits = [];

for (const v of s) {
  visits.push(v);
  if (v === "a" && visits.length === 1) {
    s.delete("a");
    s.add("a");
  }
}

console.log(visits);
console.log([...s]);

Removing many values at once

There is no bulk delete, so removal of several values is a loop; the per-item booleans show that "boat" was never in the inventory. difference() does the same job without mutating, returning a fresh collection instead.

Example · javascript
const inventory = new Set(["axe", "rope", "lamp", "map"]);
const dropped = ["rope", "map", "boat"];

const results = dropped.map((item) => [item, inventory.delete(item)]);
console.log(results);
console.log([...inventory]);

// Non-mutating alternative
console.log([...new Set(["axe", "rope"]).difference(new Set(["rope"]))]);

Discussion

  • Be the first to comment on this lesson.