Set Stores Unique Values and Tests Membership in O(1)
Sets
Master JavaScript's Set: deduplication, O(1) has() checks, and the union, intersection, and difference patterns used in interview problems.
What you'll learn
- Use Set to deduplicate an array in a single pass
- Implement union, intersection, and difference with Set operations
- Explain why has() is O(1) while Array.includes() is O(n)
A Set is a collection of unique values backed by a hash table. Because
membership is stored by hash, has() runs in O(1) average time — the same
as Map.get() — making Set the right choice whenever you need fast
existence checks or duplicate elimination.
Creating a Set
const s = new Set([1, 2, 3, 2, 1]);
console.log(s.size); // 3 — duplicates removed
console.log(s.has(2)); // true — O(1)
console.log(s.has(99)); // false — O(1)
s.add(4);
s.delete(1);
console.log([...s]); // [2, 3, 4] Deduplication
Converting an array to a Set and back is the idiomatic O(n) dedup:
const raw = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
const unique = [...new Set(raw)];
console.log(unique); // [3, 1, 4, 5, 9, 2, 6] Insertion order is preserved (same guarantee as Map), so the first
occurrence of each value survives.
Union, Intersection, Difference
JavaScript does not expose these as Set methods yet (a TC39 proposal is in progress), but they are one-liners with spread and filter:
const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);
// Union — all elements from both
const union = new Set([...a, ...b]);
console.log([...union]); // [1, 2, 3, 4, 5, 6]
// Intersection — only elements in both
const intersection = new Set([...a].filter(x => b.has(x)));
console.log([...intersection]); // [3, 4]
// Difference — elements in a but not b
const difference = new Set([...a].filter(x => !b.has(x)));
console.log([...difference]); // [1, 2] The filter step is O(n) because b.has(x) is O(1) each time — so the whole
operation is O(n), not O(n²) as it would be with nested Array.includes().
has() vs Array.includes()
| Method | Structure | Time complexity |
|---|---|---|
set.has(v) | Set | O(1) average |
map.has(k) | Map | O(1) average |
arr.includes(v) | Array | O(n) |
arr.indexOf(v) | Array | O(n) |
This difference compounds in nested loops. If you find yourself calling
array.includes() inside another loop, convert the array to a Set first.
// O(n²) — avoid
function hasDuplicateSlow(arr) {
for (let i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) !== i) return true;
}
return false;
}
// O(n) — preferred
function hasDuplicate(arr) {
return new Set(arr).size !== arr.length;
}
console.log(hasDuplicate([1, 2, 3, 1])); // true
console.log(hasDuplicate([1, 2, 3, 4])); // false Up Next
Discover WeakMap and WeakSet — the garbage-collector-friendly variants
that let you attach metadata to objects without preventing their collection.