data-structure

Exploring Sets Data Structure in TypeScript: A Comprehensive Guide

A Set holds unique values. Add a duplicate and it's silently ignored. No errors, no extra logic needed. The Set handles uniqueness for you.

20 Apr 2024

A Set holds unique values. Add a duplicate and it's silently ignored. No errors, no extra logic needed. The Set handles uniqueness for you.

This makes it the go-to data structure when you need to eliminate duplicates, check membership, or perform union/intersection operations.

Basic Usage

Typescript
const numbers = new Set<number>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
numbers.add(1); // ignored -- already exists
numbers.add(2); // ignored

console.log(numbers.size); // 3
console.log(numbers.has(2)); // true
console.log(numbers.has(4)); // false

numbers.delete(2);

for (const num of numbers) {
  console.log(num); // 1, 3
}

The Object Reference Trap

Sets use reference equality for objects, not deep equality. This catches people:

Typescript
const set = new Set<{ id: number; name: string }>();

const person = { id: 1, name: 'Ehsan' };
set.add(person);
set.add(person); // ignored -- same reference

set.add({ id: 1, name: 'Ehsan' }); // ADDED -- different reference, same data
console.log(set.size); // 2

Two objects with identical properties are still different references. If you need value-based uniqueness for objects, use a Map keyed by a unique identifier instead.

Practical Set Operations

JavaScript's Set doesn't have built-in union/intersection methods (yet), but they're easy to build:

Typescript
function union<T>(a: Set<T>, b: Set<T>): Set<T> {
  return new Set([...a, ...b]);
}

function intersection<T>(a: Set<T>, b: Set<T>): Set<T> {
  return new Set([...a].filter(x => b.has(x)));
}

function difference<T>(a: Set<T>, b: Set<T>): Set<T> {
  return new Set([...a].filter(x => !b.has(x)));
}

Deduplication One-liner

The most common use case for Sets in practice:

Typescript
const numbers = [1, 2, 2, 3, 3, 3, 4];
const unique = [...new Set(numbers)]; // [1, 2, 3, 4]

Performance

Operation Time Complexity
add O(1)
has O(1)
delete O(1)
iteration O(n)

has is the key advantage over arrays. Checking if an element exists in an array is O(n). In a Set, it's O(1). If you're doing repeated membership checks on a collection, convert it to a Set first.

When to Use Sets

  • Removing duplicates from an array or stream of values
  • Fast membership testing when you need to check "is X in this collection?" frequently
  • Tracking visited nodes in graph/tree traversal algorithms
  • Tag or category management where uniqueness is guaranteed

Sets are underused. Most developers reach for arrays by default, then write manual deduplication logic. A Set does it automatically. Reach for it whenever uniqueness matters.

Keep reading