Map and Set
Collections of unique values and dictionaries with any type of key.
Updated
What Map and Set are
Two native collections, besides arrays and objects:
Set— a collection of unique values. No keys, no duplicates.Map— a key → value dictionary, like an object, but the key can be anything (including objects) and it's optimized for frequent additions and deletions.
Set
const tags = new Set(['js', 'css', 'js'])
tags.size // 2 — the duplicate is gone
tags.has('css') // true — a very fast check
tags.add('html')
tags.delete('css')
for (const tag of tags) {} // iterable
const unique = [...new Set(arr)] // the classic recipe: remove duplicatesSet operations (native since 2024):
a.union(b) // union
a.intersection(b) // what they have in common
a.difference(b) // what's in a but not in b
a.isSubsetOf(b)Map
const cache = new Map()
cache.set('user:1', { name: 'Ana' })
cache.set(domElement, metadata) // the key can be an object!
cache.get('user:1')
cache.has('user:1')
cache.delete('user:1')
cache.size
for (const [key, value] of cache) {}
new Map(Object.entries(obj)) // from an object
Object.fromEntries(map) // back to an objectWhich collection when — a comparison
| You need... | Use | Why |
|---|---|---|
| an ordered list, duplicates allowed | Array | indexes, map/filter, JSON |
| unique values / "have I seen this already?" | Set | instant has, no duplicates |
| describing one thing with fixed fields | Object | short syntax, JSON, destructuring |
| a dynamic dictionary, keys added / removed often | Map | performance, size, guaranteed order |
| keys that are objects | Map | objects as keys don't work in {} |
Map vs object, in detail
Object {} |
Map |
|
|---|---|---|
| Key types | string / symbol (numbers become strings) | anything |
| Key order | almost always insertion (numbers first) | always insertion order |
| Size | Object.keys(o).length |
.size |
| Iterating | Object.entries(o) |
directly with for...of |
| JSON | directly | needs converting |
Accidentally inherited keys (toString) |
possible | no |
Set vs array.includes
arr.includes(x) walks the whole array on every call. set.has(x) is practically instant. The difference matters when you check often against a large list:
const passed = new Set(passedIds) // once
exercises.filter(e => passed.has(e.id)) // fast for each oneThat's exactly how this app calculates your progress.
WeakMap and WeakSet
Variants where the keys are held "weakly": if the key object isn't used anywhere anymore, it's removed automatically by the garbage collector. For metadata attached to objects (e.g. DOM nodes) without a memory leak. They're not iterable.
Summary
- Set = unique values, a fast
has; Map = a dictionary with any type of key. - An object for fixed data / JSON; a Map for dynamic collections and caches.
new Set(arr)for duplicates and fast checks.