Map & Set
Objects and arrays cover most needs, but two jobs come up again and again where they are clumsy: looking things up by a key that is not a simple string, and keeping a list without duplicates. JavaScript has two built-in collections made for exactly these jobs: Map and Set.
In this lesson you will learn how to use both, when to prefer them over objects and arrays, and the set operations added in ES2025 that make comparing groups easy.
Map: key-value pairs
A Map stores values under keys, like an object, but with methods made for the job and with keys of any type.
const stock = new Map();
stock.set("Tea", 40);
stock.set("Sugar", 12);
stock.set("Milk", 25);
console.log(stock.get("Sugar"));
console.log(stock.has("Coffee"));
console.log(stock.size);
stock.set("Sugar", 30); // same key again: updates the value
stock.delete("Milk");
for (const [item, qty] of stock) {
console.log(`${item}: ${qty}`);
}12 false 3 Tea: 40 Sugar: 30
| Method or property | Does |
|---|---|
map.set(key, value) | Adds or updates an entry (returns the map, so calls can be chained) |
map.get(key) | Returns the value, or undefined |
map.has(key) | true if the key exists |
map.delete(key) | Removes an entry |
map.size | Number of entries |
map.keys(), map.values(), map.entries() | Iterables for looping |
A Map always remembers the order in which keys were added, and for...of gives you [key, value] pairs, ready for destructuring. You can also create a Map straight from pairs: new Map([["Tea", 40], ["Sugar", 12]]), or from an object with new Map(Object.entries(obj)).
Keys of any type
Object keys are always strings (or symbols): the number 1 becomes the string "1". A Map keeps keys exactly as they are, including numbers and even objects.
const aarav = { name: "Aarav" };
const isha = { name: "Isha" };
const lastSeen = new Map([
[aarav, "10:15 am"],
[isha, "11:40 am"],
]);
console.log(lastSeen.get(isha));
const roomOf = new Map([[101, "Science lab"]]);
console.log(roomOf.get(101));
console.log(roomOf.get("101"));11:40 am Science lab undefined
Using objects as keys lets you attach extra data to an object without changing it. And the number 101 and the string "101" are different keys, so lookups are precise.
Counting with a Map
A Map is the natural tool for counting how often things appear:
const votes = ["Pune", "Kochi", "Pune", "Jaipur", "Pune", "Kochi"];
const counts = new Map();
for (const city of votes) {
counts.set(city, (counts.get(city) ?? 0) + 1);
}
for (const [city, total] of counts) {
console.log(`${city}: ${total}`);
}Pune: 3 Kochi: 2 Jaipur: 1
counts.get(city) ?? 0 gives the current count, or 0 the first time a city appears. The ?? operator comes from Nullish Coalescing & Optional Chaining. Map.groupBy() (ES2024) works like Object.groupBy() from Array Methods but returns a Map.
Map or object?
| Use a Map when | Use an object when |
|---|---|
| Keys are added and removed often | The shape is fixed, like a student record |
| Keys are not strings, or come from users | Keys are known names like name and city |
| You need the size or a guaranteed order | You need to send it as JSON |
Objects are still the right choice for records with fixed fields, and they convert to JSON directly. A Map shines as a lookup table or a counter.
Set: unique values
A Set is a collection of values where each value can appear only once. Adding a value that is already there does nothing.
const visitors = new Set();
visitors.add("Meera");
visitors.add("Rohan");
visitors.add("Meera"); // already there: ignored
console.log(visitors.size);
console.log(visitors.has("Rohan"));
const pincodes = [124001, 302001, 124001, 411001, 302001];
const uniquePincodes = [...new Set(pincodes)];
console.log(uniquePincodes);2 true [ 124001, 302001, 411001 ]
The last part is the most famous Set trick: turn an array into a Set to drop duplicates, then spread it back into an array. Sets keep insertion order, so the first appearance of each value decides its position.
Checking set.has(x) is very fast, even with a million values, while array.includes(x) has to look at items one by one. If you often ask "is this value in my list?", a Set is the better tool.
Set operations (ES2025)
ES2025 added methods that compare two Sets, just like the Venn diagrams from school maths. Each one returns a new Set and leaves the originals unchanged.
const cricket = new Set(["Aarav", "Kabir", "Isha", "Farhan"]);
const chess = new Set(["Isha", "Meera", "Kabir"]);
console.log([...cricket.union(chess)]);
console.log([...cricket.intersection(chess)]);
console.log([...cricket.difference(chess)]);
console.log([...cricket.symmetricDifference(chess)]);
console.log(new Set(["Isha", "Kabir"]).isSubsetOf(chess));
console.log(cricket.isDisjointFrom(new Set(["Rohan"])));[ 'Aarav', 'Kabir', 'Isha', 'Farhan', 'Meera' ] [ 'Isha', 'Kabir' ] [ 'Aarav', 'Farhan' ] [ 'Aarav', 'Farhan', 'Meera' ] true true
| Method | Returns |
|---|---|
a.union(b) | Everything in a or b (all club members) |
a.intersection(b) | Only what is in both (plays both games) |
a.difference(b) | In a but not in b (cricket only) |
a.symmetricDifference(b) | In exactly one of them |
a.isSubsetOf(b) | true if everything in a is also in b |
a.isSupersetOf(b) | true if a contains everything in b |
a.isDisjointFrom(b) | true if they share nothing |
Before ES2025 you had to write these with loops and filter(). They work in all current browsers.
WeakMap and WeakSet
You may also meet WeakMap and WeakSet. They only accept objects as keys (or values, for WeakSet) and do not stop those objects from being removed from memory when nothing else uses them. Libraries use them to attach private data to objects. You can safely skip them until you need them.
Common mistakes
- Using square brackets on a Map.
map["Tea"] = 40sets an ordinary property, not a Map entry, andsizestays the same. Useset()andget(). - Expecting a Set to remove duplicate objects. Two objects with the same contents are still different objects, so a Set keeps both.
- Forgetting that Map keys are exact.
map.get("101")does not find the key101. - Calling
JSON.stringify()on a Map or Set. You get{}. Convert first withObject.fromEntries(map)or[...set].
Key points
- A Map stores key-value pairs with keys of any type, remembers insertion order and has
size. - Use
set,get,hasanddelete; loop withfor...ofto get[key, value]pairs. - A Set stores unique values;
[...new Set(array)]removes duplicates. set.has()is a fast membership check.- ES2025 Set methods:
union,intersection,difference,symmetricDifference,isSubsetOf,isSupersetOf,isDisjointFrom. - ES2026 adds
getOrInsert()andgetOrInsertComputed()to Map and WeakMap.
Exercise
Two coaching classes in Lucknow share students. The morning batch is ["Aarav", "Priya", "Kabir", "Ananya"] and the evening batch is ["Kabir", "Isha", "Ananya", "Rohan"]. Using Sets, print the total number of different students, the students who attend both batches, and the students who attend only the morning batch. Then use a Map to store each student's fee (₹3000 for one batch, ₹5000 for both) and print Kabir's fee.
Show solution
const morning = new Set(["Aarav", "Priya", "Kabir", "Ananya"]);
const evening = new Set(["Kabir", "Isha", "Ananya", "Rohan"]);
const everyone = morning.union(evening);
const both = morning.intersection(evening);
console.log("Students:", everyone.size);
console.log("Both batches:", [...both]);
console.log("Morning only:", [...morning.difference(evening)]);
const fees = new Map();
for (const student of everyone) {
fees.set(student, both.has(student) ? 5000 : 3000);
}
console.log("Kabir pays ₹" + fees.get("Kabir"));Students: 6 Both batches: [ 'Kabir', 'Ananya' ] Morning only: [ 'Aarav', 'Priya' ] Kabir pays ₹5000
The Set methods answer each question in one line, and both.has(student) is a fast check while filling the Map.
Quick Quiz
1. What is new Set([1, 2, 2, 3, 3, 3]).size?
A Set keeps each value only once, so only 1, 2 and 3 remain.
2. Which Map method adds or updates an entry?
set(key, value) adds a new key or replaces the value of an existing one. Sets use add().
3. What does a.intersection(b) return?
Intersection is the overlap of the two Sets; difference() gives the values only in a.
4. Why might you choose a Map instead of an object?
Map keys keep their type, while object keys are converted to strings.
Learn JavaScript with a mentor
Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.
- Project-based learning
- Mentor code reviews
- Free counselling call
