Map & Set

JavaScript · Lesson 25 of 61 7 min read Updated

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.

JavaScriptRun it yourself
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}`);
}
Output
12
false
3
Tea: 40
Sugar: 30
Method or propertyDoes
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.sizeNumber 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.

JavaScriptRun it yourself
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"));
Output
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:

JavaScriptRun it yourself
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}`);
}
Output
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 whenUse an object when
Keys are added and removed oftenThe shape is fixed, like a student record
Keys are not strings, or come from usersKeys are known names like name and city
You need the size or a guaranteed orderYou 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.

JavaScriptRun it yourself
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);
Output
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.

JavaScriptRun it yourself
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"])));
Output
[ 'Aarav', 'Kabir', 'Isha', 'Farhan', 'Meera' ]
[ 'Isha', 'Kabir' ]
[ 'Aarav', 'Farhan' ]
[ 'Aarav', 'Farhan', 'Meera' ]
true
true
MethodReturns
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"] = 40 sets an ordinary property, not a Map entry, and size stays the same. Use set() and get().
  • 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 key 101.
  • Calling JSON.stringify() on a Map or Set. You get {}. Convert first with Object.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, has and delete; loop with for...of to 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() and getOrInsertComputed() 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
JavaScript
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"));
Output
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?

2. Which Map method adds or updates an entry?

3. What does a.intersection(b) return?

4. Why might you choose a Map instead of an object?

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