Map & Set

Med

Map and Set are ES6 collections that solve limitations of plain objects and arrays. Map allows any value as a key (not just strings), maintains insertion order, and has a size property. Set stores only unique values with O(1) lookup.

Interactive Visualization

Built-in Data Structures

"age":30

Key Points

  • Map keys can be any type (objects, functions, primitives) unlike object keys which are always strings/symbols
  • Map preserves insertion order and has a .size property
  • Set stores only unique values with O(1) add/has/delete
  • Both Map and Set are iterable with for...of, forEach, and spread
  • Use Map when you need non-string keys or frequent additions/deletions
  • Convert between arrays and Map/Set with spread and constructors

Code Examples

Map vs Plain Object

const map = new Map()

const objKey = { id: 1 }
map.set(objKey, 'user data')
map.set(42, 'numeric key')

console.log(map.get(objKey))  // 'user data'
console.log(map.size)         // 2
console.log(map.has(42))      // true

// Plain object coerces keys to strings
const obj = {}
obj[objKey] = 'user data'
console.log(Object.keys(obj)) // ['[object Object]'] — key is lost!

Map preserves the actual key identity. Objects stringify all keys, losing the original reference.

Set for Unique Values

const nums = [1, 2, 3, 2, 1, 4, 5, 4]
const unique = new Set(nums)
console.log(unique)      // Set {1, 2, 3, 4, 5}
console.log(unique.size) // 5

console.log(unique.has(3))  // true

const arr = [...unique]     // [1, 2, 3, 4, 5]

// Set operations
const a = new Set([1, 2, 3])
const b = new Set([2, 3, 4])
const union = new Set([...a, ...b])
const intersection = new Set([...a].filter(x => b.has(x)))

Set automatically removes duplicates and provides fast lookups. Spread and filter enable set algebra.

Map Methods and Iteration

const userRoles = new Map([
  ['alice', 'admin'],
  ['bob', 'editor'],
  ['charlie', 'viewer'],
])

for (const [name, role] of userRoles) {
  console.log(`${name}: ${role}`)
}

console.log([...userRoles.keys()])   // ['alice', 'bob', 'charlie']
console.log([...userRoles.values()]) // ['admin', 'editor', 'viewer']

userRoles.delete('bob')
userRoles.clear()

Map provides keys(), values(), entries() iterators. Iteration always follows insertion order.

When to Use Map vs Object

// Use Map when: non-string keys, frequent add/delete, need size
const wordFreq = new Map()
for (const word of ['hi', 'bye', 'hi']) {
  wordFreq.set(word, (wordFreq.get(word) || 0) + 1)
}
console.log(wordFreq.size) // 2

// Use Object when: fixed-shape, JSON, destructuring
const config = { theme: 'dark', lang: 'en' }
JSON.stringify(config)  // works
const { theme } = config // works

Map excels with dynamic keys and frequent mutations. Objects are better for fixed-shape records and JSON.

Common Mistakes

  • Using map[key] instead of map.get(key) — bracket notation does not use the Map API
  • Expecting Map to be JSON-serializable — use Object.fromEntries(map) to convert first
  • Comparing objects by value in Set — Set uses reference equality
  • Forgetting that Map.forEach callback order is (value, key) not (key, value)

Interview Tips

  • Map/Set get/set/has/delete are all O(1) average case
  • Array deduplication with Set: [...new Set(arr)]
  • Explain when Map is better than Object: non-string keys, frequent add/delete, size tracking
  • Map preserves insertion order — guaranteed by the spec

Related Concepts