🌱BeginnerData Structures
Sets and Maps
ES6 Set and Map unique value collections and key-value stores with any key type.
Overview
ES6 introduced `Set` and `Map` as first-class collection types to complement arrays and plain objects.
**Set** is a collection of unique values duplicates are automatically ignored. It's perfect for deduplication, membership checks, and set operations (union, intersection, difference). Unlike arrays, Sets have O(1) `.has()` lookups.
**Map** is a key-value store like a plain object, but with crucial advantages: keys can be any value (not just strings), insertion order is preserved, and Maps have cleaner size/iteration APIs. Use a Map when you need non-string keys, need to count occurrences, or need a clean key-value API without the prototype clutter of plain objects.
Both are iterable with `for...of` loops and support the spread operator: `[...mySet]`, `[...myMap]`.
Key Points
- •`new Set([iterable])` unique values; `.add(v)`, `.has(v)`, `.delete(v)`, `.size`, `.clear()`
- •`[...new Set(array)]` the fastest way to remove duplicates from an array
- •`new Map([[key, val], ...])` key-value store; `.set(k, v)`, `.get(k)`, `.has(k)`, `.delete(k)`, `.size`
- •Map keys can be objects, functions, numbers any value; plain object keys are always strings
- •Both preserve insertion order and are iterable with `for...of`
- •`map.entries()` iterator of `[key, value]` pairs; `map.keys()`, `map.values()`
- •WeakSet and WeakMap hold weak references good for caching without preventing garbage collection
Examples
Set unique values and membership
// Create a Set
const fruits = new Set(["apple", "banana", "apple", "cherry"]);
console.log(fruits); // Set(3) {"apple", "banana", "cherry"}
console.log(fruits.size); // 3
// Add and check
fruits.add("mango");
fruits.add("apple"); // duplicate ignored
console.log(fruits.has("banana")); // true
console.log(fruits.has("grape")); // false
// Remove duplicates from an array
const nums = [1, 2, 2, 3, 3, 3, 4];
const unique = [...new Set(nums)];
console.log(unique); // [1, 2, 3, 4]
// Set operations
const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);
const union = new Set([...a, ...b]); // {1,2,3,4,5,6}
const intersection = new Set([...a].filter(x => b.has(x))); // {3,4}
const difference = new Set([...a].filter(x => !b.has(x))); // {1,2}
console.log([...union], [...intersection], [...difference]);Map flexible key-value store
// Create a Map
const scores = new Map();
scores.set("Alice", 95);
scores.set("Bob", 87);
scores.set("Carol", 92);
console.log(scores.get("Alice")); // 95
console.log(scores.has("Dave")); // false
console.log(scores.size); // 3
// Non-string keys
const userMap = new Map();
const userObj = { id: 1 };
userMap.set(userObj, { role: "admin" });
console.log(userMap.get(userObj)); // {role: "admin"}
// Iterate
for (const [name, score] of scores) {
console.log(`${name}: ${score}`);
}
// Convert Map to object
const obj = Object.fromEntries(scores);
console.log(obj); // {Alice: 95, Bob: 87, Carol: 92}Map for counting occurrences
function countWords(text) {
const counts = new Map();
for (const word of text.toLowerCase().split(/\s+/)) {
counts.set(word, (counts.get(word) ?? 0) + 1);
}
return counts;
}
const wc = countWords("the quick brown fox jumps over the lazy fox");
console.log(wc.get("the")); // 2
console.log(wc.get("fox")); // 2
// Sort by count convert to array first
const sorted = [...wc.entries()].sort((a, b) => b[1] - a[1]);
sorted.slice(0, 3).forEach(([w, c]) => console.log(`${w}: ${c}`));Common Mistakes
- Using `.length` on a Set or Map they use `.size`, not `.length`
- Accessing Map values with bracket notation (`map["key"]`) this sets a plain property, not a Map entry; always use `.get()` and `.set()`
- Expecting that two object literals with the same content are the same key in a Map `map.set({a:1}, x)` and `map.get({a:1})` returns `undefined` because they're different object references
Note
Rule of thumb: use a Set when you care about uniqueness; use a Map when you need non-string keys or want cleaner semantics than a plain object. For most string-key lookups where you own the keys, a plain object `{}` is simpler and faster.
Exercises
Write JavaScript code to solve each exercise. Run it and check your output.
Loading editor…
Completed: 0 / 5 exercises
Knowledge Check
Question 1 of 4