Set in JavaScript: More Than Just Removing Duplicates
A reflection on JavaScript Set as more than a duplicate remover, showing how it acts as an efficient way to track existence and enforce uniqueness by identity.
The first time you encounter Set, it usually looks like a small convenience.
const set = new Set([1, 2, 2, 3])
// {1, 2, 3}It removes duplicates.
Thatâs useful â but if thatâs all you see, youâre missing the bigger idea.
Because Set is not really about removing duplicates.
Itâs about tracking existence efficiently.
From Lists to Questions
Arrays are great when you care about order.
const arr = [1, 2, 3]You can loop, sort, index, and manipulate positions.
But the moment your problem becomes:
âHave I seen this value before?âarrays start to feel awkward.
You end up writing patterns like:
if (!arr.includes(value)) {
arr.push(value)
}This works, but it reveals something:
Youâre not really treating the array as a list anymore.
Youâre treating it as a membership tracker.
And thatâs exactly what Set is designed for.
Set as an Existence Tracker
A Set answers a very specific question:
Does this value exist?const set = new Set()
set.add(1)
set.add(2)
set.has(1) // true
set.has(3) // falseThis is not just cleaner â itâs also more efficient.
Checking existence in an array requires scanning through it.
A Set is optimized to answer that question quickly.
So instead of thinking of Set as âarray without duplicatesâ, itâs more useful to think:
Set = fast way to track what existsWhat Counts as âThe Same Valueâ?
This is where things become interesting.
With primitives:
const set = new Set()
set.add(1)
set.add(1)
set.size // 1No surprise there.
But with objects:
set.add({ id: 1 })
set.add({ id: 1 })
set.size // 2Now it behaves differently.
Even though the objects look identical, they are different in memory.
So Set treats them as different values.
This reveals an important detail:
Set enforces uniqueness by identity, not by meaningJavaScript does not know what âduplicateâ means in your domain.
It only knows whether two values are literally the same reference.
When Set Doesnât Do What You Expect
This behavior often surprises developers when working with real data.
const users = [
{ id: 1 },
{ id: 1 }
]
const unique = new Set(users)You might expect one user.
But you get two.
Because Set is not comparing the id.
Itâs comparing the object references.
To enforce uniqueness based on id, you need to define that rule yourself â often using a Map or a derived key.
This is where understanding the limitation becomes more important than the feature itself.
Where Set Fits Naturally
Set becomes very natural in problems where duplication is the concern.
Tracking visited items:
const visited = new Set()
function visit(node) {
if (visited.has(node)) return
visited.add(node)
}Filtering duplicates:
const unique = [...new Set(list)]Checking permissions:
const allowed = new Set(["admin", "editor"])
if (allowed.has(role)) {
// allowed
}Preventing repeated processing:
if (processed.has(eventId)) return
processed.add(eventId)In all these cases, the pattern is the same:
Have I seen this before?A Subtle Relationship with Map
Thereâs a useful way to connect Set to something you already understand.
Conceptually:
Set = Map where value is also the keyWhen you do:
set.add(x)itâs similar to:
map.set(x, true)This explains why Set behaves like a collection of unique keys rather than key-value pairs.
A Shift in Perspective
Itâs easy to think of Set as a small utility.
But it actually represents a different way of thinking about data.
Arrays are about:
order and positionObjects and Maps are about:
relationships between keys and valuesSet is about:
presence and uniquenessOnce you start recognizing that pattern, youâll see situations where Set feels like the natural choice â not just a convenient one.
What Set Really Teaches
Set introduces a simple but powerful idea:
Sometimes you donât care about the data itself.
You care about whether it has already appeared.
And when thatâs the problem youâre solving, Set stops being a minor feature and becomes exactly the right tool.