Sets

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.

4 min read Level 1/5 #dsa#hashing#set
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()

MethodStructureTime complexity
set.has(v)SetO(1) average
map.has(k)MapO(1) average
arr.includes(v)ArrayO(n)
arr.indexOf(v)ArrayO(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.

WeakMap and WeakSet →