Removing a value
s.delete(x) takes x out of the set s. It returns true if x was there. If it wasn't, nothing happens: there is no error, and the call returns false.
let colors = new Set(["red", "blue", "green"]);
console.log(colors.delete("blue")); // true
console.log(colors.delete("pink")); // false, it was never there
true
false
That makes delete safe to call without checking has first.
Looping over a set
for (let x of s) visits each value of the set once.
for (let color of colors) {
console.log(color);
}
red
green
A JavaScript set loops in the order the values were added. Most languages don't promise any order for a set, so a set is best for work where the order doesn't matter: a total, a count or a check.
Traps
- No indexes. A
forloop withiands[i]doesn't work on a set. With the set of four words from the exercise below,found[0],found[1]and so on are allundefined. Usefor...of. - The wrong method name. Arrays use
spliceorpopto remove values. A set usesdelete. - Type matters. A set compares values exactly. For
new Set([1, 2, 3]),delete("1")returnsfalseand leaves the size at 3, because the text "1" is not the number 1. Thendelete(1)returnstrueand the size drops to 2. - Re-adding goes to the end. If you delete a value and add it again, it counts as newly added, so it is visited last. After deleting 3 from
[3, 1, 2]and adding it back, the loop visits 1, 2, 3. - Counting with
length. Usesize.
The exercise, step by step
In a word game, the set found holds the words a player found. The words "qqq" and "zzz" aren't allowed, so both must be removed. The player never found "zzz", so that removal changes nothing. Then the score is one point per letter, so the task is to add each word's length to score.
- Call
deleteonfoundwith "qqq", then with "zzz", one call per line. - Below
let score = 0;, write afor...ofloop overfound, with the loop variableword. - Inside the loop, add
word.lengthtoscore.
let words = ["cat", "tree", "sun", "qqq", "moon"];
let found = new Set(words);
found.delete("qqq");
found.delete("zzz");
console.log(found.size + " words");
let score = 0;
for (let word of found) {
score += word.length;
}
console.log(score + " points");
The output is:
4 words
14 points
The four words left are cat, tree, sun and moon, with 3 + 4 + 3 + 4 = 14 letters. Because a total doesn't depend on the order, the loop gives 14 however the words are visited.
Using the answer from delete
Because delete says whether the value was there, you can count real removals. Here two words are removed from the exercise's set, and only "qqq" was present:
let found = new Set(["cat", "tree", "sun", "qqq", "moon"]);
let removed = 0;
for (const w of ["qqq", "zzz"]) {
if (found.delete(w)) {
removed += 1;
}
}
console.log(removed, found.size);
1 4
To empty a whole set at once, call found.clear(); its size is then 0.
Deleting while looping
JavaScript lets you call delete on the set you are looping over: the loop skips values that are already gone and carries on. This code empties a set and ends with a size of 0:
let live = new Set([1, 2, 3]);
for (const x of live) {
live.delete(x);
}
console.log(live.size);
0
Key takeaways
s.delete(x)removesxand returns whether it was there; a missing value is not an error.for (let x of s)visits every value once, in the order they were added.- Sets have no indexes, so loop with
for...of. - Totals, counts and checks give the same answer in any order.
