Lesson 40: Mastering JavaScript Map and Set with challenges!

manoj ymkmanoj ymk
6 min read

🔷 Map: Keyed Collections With Any Data Type

A Map stores key–value pairs, like an Object, but:

  • Keys can be of any type: object, number, boolean, NaN, etc.

  • Maintains insertion order.

  • Has a clean, iterable API.

const map = new Map();

map.set('name', 'Alice');   // string key
map.set(42, 'answer');      // number key
map.set(true, 'truthy');    // boolean key
map.set(NaN, 'not-a-number'); // NaN is a valid key

console.log(map.get(42)); // "answer"
console.log(map.get(NaN)); // "not-a-number"

🔷 Set: Unique Value Collections

A Set is like an array, but:

  • Only stores unique values.

  • No key–value pairs — just values.

  • Maintains insertion order.

const set = new Set();

set.add('apple');
set.add('banana');
set.add('apple'); // ignored

console.log(set.has('banana')); // true
console.log(set.size); // 2

🔷 Visual Overview

Map                          Set
──────                      ──────
Key => Value                Value
"foo" => 123                "foo"
42     => "bar"             42
{a: 1} => "baz"             {a: 1}

🔷 Comparison Table

FeatureMapSet
StoresKey-value pairsUnique values
KeysAny type (object, etc.)Not applicable
Value uniquenessNot enforcedEnforced
OrderInsertion order preservedInsertion order
Iteration.entries(), .keys().values(), .keys()
ChainingYes (map.set().set())Yes (set.add().add())

🔹 2. Fill Any Gaps


🔸 Hidden Mechanics and Tricky Concepts

Key comparison: SameValueZero

  • Like === but treats NaN === NaN.
const m = new Map();
m.set(NaN, "works");
console.log(m.get(NaN)); // works

⚠️ map[key] is dangerous

const m = new Map();
m['x'] = 42; // NOT stored as a real Map key
console.log(m.get('x')); // undefined

This stores x as a property on the Map object — not a map entry.


🔸 Objects as keys

let user = { name: 'John' };
const visits = new Map();
visits.set(user, 1);

console.log(visits.get({ name: 'John' })); // undefined (new object !== user)

🔹 Objects must be the same reference!


🔸 Iteration and destructuring

for (const [key, value] of map) {
  console.log(key, value);
}

Map and Set are both iterable, unlike plain objects.


🔸 Performance Edge

  • Set and Map use hash maps internally for near O(1) lookup speed.

  • Arrays and Objects require linear or slow property name string coercion.


🔸 Set.forEach quirk

set.forEach((value, valueAgain, setRef) => {
  console.log(value, valueAgain); // both are the same
});

Just for compatibility with Map, where you have (value, key, map).


🔸 Object.fromEntries vs Object.entries

// Object to Map
const map = new Map(Object.entries({ a: 1, b: 2 }));

// Map to Object
const obj = Object.fromEntries(map);

Perfect for converting between API inputs/outputs and modern usage.


🔸 Browser-specific oddities

All modern browsers fully support Map/Set, but:

  • Old IE (pre-Edge) lacks them.

  • Some devs misuse .forEach() on Sets due to its signature (see above).


🔹 3. Challenge Me Deeply


🟢 Basic

  1. Create a Map to store user scores where keys are usernames (strings), and retrieve a score.

  2. Create a Set that filters out duplicate numbers from an array.

  3. Add objects as keys in a Map and retrieve their values.

🟡 Intermediate

  1. Convert an object to a Map, then back to an object using Object.entries and Object.fromEntries.

  2. Given two arrays, find the intersection using Set.

  3. Use chaining to populate a Map with 5 values and print all keys.

  4. Track unique visitors (objects) with a Set, ensuring no repeats are added.

🔴 Advanced

  1. Implement a frequency counter using Map from a string of words.

  2. Create a cache system using Map where function results are stored and reused.

  3. Simulate a database row update tracker using objects as keys in a Map.

🎯 Bonus (Brain Twister)

  1. Why does the following code return undefined?
let map = new Map();
map.set('1', 'string one');
console.log(map.get(1));

→ What change fixes it, and why?


🔹 4. Interview-Ready Questions


✅ Conceptual

  • What’s the difference between Map and Object?

  • How does a Set differ from an array?

  • Why can’t we use Object keys for objects?

🧩 Debugging

  • Why does map[objectKey] = 'value' not work as expected?

  • Why is map.get(NaN) working when NaN !== NaN?

💼 Scenario-Based

  • How would you prevent duplicate requests from being cached?

  • You receive a list of users — how would you track unique visitors?


✔ Best Practices

✅ Use Map when:

  • Keys are non-strings (e.g., DOM nodes, objects)

  • You care about insertion order

  • Need frequent key lookups

✅ Use Set when:

  • You need to ensure uniqueness

  • You want fast lookups with no duplicate values


❌ Red Flags

  • Misusing map[key] instead of map.get(key)

  • Using Set but still doing duplicate checks manually

  • Using arrays for uniqueness checks instead of Sets


🔹 5. Real-World Usage


🔸 In Frameworks

  • React / Redux: Caching computations with Map

  • Node.js: Tracking connected sockets in Set

  • D3.js: Storing references to DOM nodes with Map

🔸 Example Use Cases

  • Caching: Store API responses with request objects as keys

  • Deduplication: Eliminate repeated emails in a mailing list

  • Tracking: Store DOM nodes as keys to values (e.g., tooltips, listeners)


🔹 6. Remember Like a Pro


🎯 Mnemonic

MAP = “Many Any Pairs”

“Many pairs, keys of Any type, Preserves order”

SET = “Single Entry Type”

“Set has Single instances, Ensures uniqueness, Treats values like keys”


🗺️ Cheatsheet

MethodMapSet
Addset(key, value)add(value)
Getget(key)has(value)
Removedelete(key)delete(value)
Sizemap.sizeset.size
Clearclear()clear()
Iteratefor..of / .forEachSame
Init from arraynew Map([[k,v]])new Set([v])

🔹 7. Apply It in a Fun Way


🛠️ Mini Project: Unique Comment Tracker

Track unique users commenting on a blog and how many times they commented.


🧩 Steps:

  1. Create a Map to track { userObj => commentCount }

  2. For each comment, check if user exists in Map

  3. If not, initialize count to 1

  4. If yes, increment count

  5. Display total unique users and top commenters


Example Logic:

const commentMap = new Map();

function trackComment(user) {
  if (!commentMap.has(user)) {
    commentMap.set(user, 1);
  } else {
    commentMap.set(user, commentMap.get(user) + 1);
  }
}

➕ Extension Ideas

  • Sort users by comment count

  • Convert Map to object and export as JSON

  • Track comment timestamps with a Map<user, [timestamps]>


🧠 Optional Bonus


🔍 Used In:

  • React Fiber — internal maps to track fiber trees

  • Babel — uses Maps for scope resolution

  • [Webpack] — uses Sets to track visited modules


❌ Common Mistakes

  • Using arrays to deduplicate data

  • Expecting Set to prevent object duplication by value (doesn't work!)

  • Mutating keys (objects) in Maps after insertion — breaks access


⚡ Performance Tips

  • Use Set for large-scale deduplication

  • Use Map over Object for frequently changing collections

  • Avoid converting between Map and Object too often — not free

0
Subscribe to my newsletter

Read articles from manoj ymk directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

manoj ymk
manoj ymk