Map and Set in JavaScript

Map and Set are better ways to store data than objects and arrays. Map stores paired data like objects, but works with any data type as keys. Set stores only unique values, making duplicates impossible. Both are faster and more predictable than their traditional counterparts.
This is about understanding Map and Set and knowing when to use them.
What is Map?
Map is a data structure for storing key-value pairs. Like an object, but better.
Simple Definition
A Map is a collection of paired data: each key has a value.
// Empty Map
const map = new Map();
// Add key-value pairs
map.set("name", "Alice");
map.set("age", 25);
map.set("email", "alice@example.com");
// Get values
console.log(map.get("name")); // "Alice"
console.log(map.get("age")); // 25
console.log(map.get("email")); // "alice@example.com"
Creating a Map
// Empty Map
const emptyMap = new Map();
// Map from array of pairs
const mapFromArray = new Map([
["name", "Alice"],
["age", 25],
["city", "NYC"]
]);
// Map from another Map
const copyMap = new Map(mapFromArray);
Basic Map Methods
const map = new Map();
// Add
map.set("key1", "value1");
map.set("key2", "value2");
// Get
console.log(map.get("key1")); // "value1"
// Check if exists
console.log(map.has("key1")); // true
console.log(map.has("key3")); // false
// Delete
map.delete("key1");
console.log(map.has("key1")); // false
// Clear all
map.clear();
console.log(map.size); // 0
// Size
map.set("a", 1);
map.set("b", 2);
console.log(map.size); // 2
Real Example: User Preferences
const userPreferences = new Map();
userPreferences.set("theme", "dark");
userPreferences.set("language", "en");
userPreferences.set("notifications", true);
userPreferences.set("timezone", "UTC");
// Check preference
if (userPreferences.has("theme")) {
console.log("Theme:", userPreferences.get("theme"));
}
// Update
userPreferences.set("theme", "light");
// Iterate
userPreferences.forEach((value, key) => {
console.log(`\({key}: \){value}`);
});
What is Set?
Set is a collection of unique values. No duplicates allowed.
Simple Definition
A Set is a collection where each value appears only once. Duplicates are automatically removed.
// Create Set
const set = new Set();
// Add values
set.add("apple");
set.add("banana");
set.add("orange");
set.add("apple"); // Duplicate, ignored
console.log(set); // Set(3) { 'apple', 'banana', 'orange' }
Only three items, not four. The duplicate "apple" was ignored.
Creating a Set
// From array
const set = new Set([1, 2, 3, 4, 4, 5, 5, 5]);
console.log(set); // Set(5) { 1, 2, 3, 4, 5 }
// From string
const charSet = new Set("hello");
console.log(charSet); // Set(4) { 'h', 'e', 'l', 'o' }
// Empty Set
const emptySet = new Set();
Basic Set Methods
const set = new Set();
// Add
set.add(1);
set.add(2);
set.add(3);
// Check if exists
console.log(set.has(2)); // true
console.log(set.has(4)); // false
// Delete
set.delete(2);
console.log(set.has(2)); // false
// Clear all
set.clear();
console.log(set.size); // 0
// Size
set.add(1);
set.add(2);
console.log(set.size); // 2
// Iterate
set.forEach((value) => {
console.log(value);
});
Real Example: Unique Tags
const tags = new Set();
// User adds tags
tags.add("javascript");
tags.add("webdev");
tags.add("node.js");
tags.add("javascript"); // Duplicate ignored
console.log(tags.size); // 3
// Check tag exists
if (tags.has("webdev")) {
console.log("Has webdev tag");
}
// Remove tag
tags.delete("node.js");
// Convert back to array
const tagArray = Array.from(tags);
console.log(tagArray); // ['javascript', 'webdev']
Set Uniqueness Representation
Adding values to a Set
|
v
[1, 2, 3, 4, 4, 5, 5]
| | | |
├─────┼─────┼─────┤
v v v v
Add 1: ✓ (new)
Add 2: ✓ (new)
Add 3: ✓ (new)
Add 4: ✓ (new)
Add 4: ✗ (duplicate, ignored)
Add 5: ✓ (new)
Add 5: ✗ (duplicate, ignored)
Add 5: ✗ (duplicate, ignored)
|
v
Result: Set(5) { 1, 2, 3, 4, 5 }
Difference Between Map and Object
Objects Store Key-Value Pairs Too
const obj = {
name: "Alice",
age: 25,
email: "alice@example.com"
};
console.log(obj.name); // "Alice"
console.log(obj["age"]); // 25
Objects look similar to Map. But there are important differences.
Difference 1: Key Types
Objects accept only strings and symbols as keys:
const obj = {};
obj["name"] = "Alice"; // ✓ String key
obj[1] = "one"; // ✗ Converted to string "1"
obj[true] = "yes"; // ✗ Converted to string "true"
console.log(obj[1]); // "one" (key is "1", not 1)
Maps accept any data type as keys:
const map = new Map();
map.set("name", "Alice"); // ✓ String key
map.set(1, "one"); // ✓ Number key
map.set(true, "yes"); // ✓ Boolean key
map.set({}, "object key"); // ✓ Object key
map.set([], "array key"); // ✓ Array key
console.log(map.get(1)); // "one" (key is number 1, not "1")
Difference 2: Size Property
Objects don't have a size property:
const obj = { a: 1, b: 2, c: 3 };
console.log(obj.length); // undefined
// Must count keys manually
console.log(Object.keys(obj).length); // 3
Maps have a size property:
const map = new Map([["a", 1], ["b", 2], ["c", 3]]);
console.log(map.size); // 3 (instant)
Difference 3: Iteration
Objects need Object.keys() or for...in:
const obj = { name: "Alice", age: 25 };
// Need to get keys first
Object.keys(obj).forEach(key => {
console.log(`\({key}: \){obj[key]}`);
});
// Or use for...in (but gets inherited properties too)
for (let key in obj) {
console.log(`\({key}: \){obj[key]}`);
}
Maps iterate directly:
const map = new Map([["name", "Alice"], ["age", 25]]);
// Iterate directly
map.forEach((value, key) => {
console.log(`\({key}: \){value}`);
});
// Or use for...of
for (const [key, value] of map) {
console.log(`\({key}: \){value}`);
}
Difference 4: Performance
Maps are optimized for frequent additions/deletions:
// Adding/deleting from objects is slower
const obj = {};
for (let i = 0; i < 10000; i++) {
obj[i] = i;
}
delete obj[5000]; // Slower
// Maps are faster
const map = new Map();
for (let i = 0; i < 10000; i++) {
map.set(i, i);
}
map.delete(5000); // Faster
Difference 5: Prototype Chain
Objects inherit from Object.prototype:
const obj = {};
console.log(obj.toString); // Inherited from Object.prototype
Maps don't have this baggage:
const map = new Map();
console.log(map.toString); // undefined (unless explicitly set)
When to Use Map vs Object
| Situation | Use Map | Use Object |
|---|---|---|
| Many key-value pairs | Yes | No (slower) |
| Non-string keys | Yes | No (converted) |
| Need size property | Yes | No |
| Need frequent add/delete | Yes | No |
| JSON serialization | No | Yes |
| Simple configuration | No | Yes |
| Performance critical | Yes | No |
Difference Between Set and Array
Arrays Store Values Too
const arr = [1, 2, 3, 4, 5];
console.log(arr[0]); // 1
console.log(arr.length); // 5
Arrays look similar to Set. But there are key differences.
Difference 1: Uniqueness
Arrays allow duplicates:
const arr = [1, 2, 3, 4, 4, 5, 5, 5];
console.log(arr.length); // 8 (includes duplicates)
Sets don't allow duplicates:
const set = new Set([1, 2, 3, 4, 4, 5, 5, 5]);
console.log(set.size); // 5 (duplicates removed)
Difference 2: Checking Membership
Arrays need to search:
const arr = [1, 2, 3, 4, 5];
// Slow for large arrays
console.log(arr.includes(3)); // true
console.log(arr.indexOf(3)); // 2
Sets have instant lookup:
const set = new Set([1, 2, 3, 4, 5]);
console.log(set.has(3)); // true (instant, very fast)
Difference 3: Iteration Methods
Arrays have many methods:
const arr = [1, 2, 3, 4, 5];
arr.map(x => x * 2); // Transform
arr.filter(x => x > 2); // Filter
arr.reduce((a, b) => a + b); // Aggregate
arr.find(x => x === 3); // Find one
arr.some(x => x > 3); // Check any
arr.every(x => x > 0); // Check all
Sets have basic iteration:
const set = new Set([1, 2, 3, 4, 5]);
// Can use spread operator for array methods
[...set].map(x => x * 2);
[...set].filter(x => x > 2);
Difference 4: Order
Arrays maintain insertion order (always):
const arr = [5, 1, 3, 2, 4];
console.log(arr[0]); // 5 (original order)
Sets maintain insertion order (in modern JS):
const set = new Set([5, 1, 3, 2, 4]);
// Iteration order: 5, 1, 3, 2, 4
set.forEach(val => console.log(val));
Difference 5: Memory Usage
Arrays use less memory for small amounts:
const arr = [1, 2, 3]; // Small array
Sets use more memory for small amounts, less for large:
const set = new Set([1, 2, 3]); // More memory overhead initially
For large collections with duplicates, Sets win.
When to Use Set vs Array
| Situation | Use Set | Use Array |
|---|---|---|
| Unique values only | Yes | No |
| Need .map(), .filter() | No | Yes |
| Checking membership | Yes | No (slower) |
| Many duplicates | Yes | No |
| Need specific order | No | Yes |
| Simple list | No | Yes |
| Performance critical | Yes | No |
Map Key-Value Storage Visual
Map Storage
|
├─ Key: "name" → Value: "Alice"
|
├─ Key: 25 → Value: "age"
|
├─ Key: true → Value: "verified"
|
└─ Key: {id: 1} → Value: "user object"
Each key maps to exactly one value
Keys can be ANY data type
Fast lookup by key
When to Use Map and Set
Use Map When
You need key-value storage with:
// Complex keys
const cache = new Map();
cache.set({ userId: 1 }, { name: "Alice", email: "alice@example.com" });
cache.set({ userId: 2 }, { name: "Bob", email: "bob@example.com" });
console.log(cache.get({ userId: 1 })); // Won't work (different object)
Or frequent additions/deletions:
const sessions = new Map();
// Add session
sessions.set("session-123", { userId: 1, time: Date.now() });
// Check if exists
if (sessions.has("session-123")) {
console.log("Session valid");
}
// Remove when expired
sessions.delete("session-123");
// How many sessions?
console.log(sessions.size);
Map Real Examples
Caching:
const cache = new Map();
function getUser(id) {
if (cache.has(id)) {
return cache.get(id);
}
const user = fetchUserFromDatabase(id);
cache.set(id, user);
return user;
}
User preferences:
const preferences = new Map();
preferences.set("theme", "dark");
preferences.set("language", "en");
preferences.set("notifications", true);
console.log(preferences.get("theme"));
Use Set When
You need unique values:
// Remove duplicates
const tags = new Set(["javascript", "webdev", "javascript", "node"]);
console.log(tags); // Set { 'javascript', 'webdev', 'node' }
// Check membership
if (tags.has("javascript")) {
console.log("Has javascript tag");
}
Or checking membership is critical:
// Fast lookup for permissions
const adminUsers = new Set(["user123", "user456", "user789"]);
if (adminUsers.has(userId)) {
console.log("Admin access granted");
}
Set Real Examples
Unique values:
// Get unique users who visited page
const visitors = new Set();
visitors.add("alice");
visitors.add("bob");
visitors.add("alice"); // Ignored
console.log(visitors.size); // 2
Allowed values:
// Valid statuses
const validStatuses = new Set(["pending", "active", "completed", "cancelled"]);
function isValidStatus(status) {
return validStatuses.has(status);
}
console.log(isValidStatus("active")); // true
console.log(isValidStatus("invalid")); // false
Remove duplicates from array:
const numbers = [1, 2, 3, 3, 4, 4, 5, 5, 5];
const unique = [...new Set(numbers)];
console.log(unique); // [1, 2, 3, 4, 5]
Problems with Objects and Arrays
Objects have issues:
const obj = {};
// All keys become strings
obj[1] = "one";
obj[true] = "yes";
obj[{id: 1}] = "object";
console.log(Object.keys(obj)); // ['1', 'true', '[object Object]']
// Lost the original types!
Arrays have issues with duplicates:
const arr = [1, 2, 3, 3, 4, 4, 5];
// No built-in way to check uniqueness
console.log(arr.length); // 7 (includes duplicates)
// Checking membership is slow
arr.includes(3); // Linear search O(n)
Complete Practical Examples
Example 1: User Roles with Map
const userRoles = new Map();
// Add users and their roles
userRoles.set(1, ["user", "admin"]);
userRoles.set(2, ["user"]);
userRoles.set(3, ["user", "moderator"]);
// Check role
function hasRole(userId, role) {
const roles = userRoles.get(userId);
return roles && roles.includes(role);
}
console.log(hasRole(1, "admin")); // true
console.log(hasRole(2, "admin")); // false
// Update roles
userRoles.set(2, ["user", "admin"]);
// Remove user
userRoles.delete(3);
// How many users?
console.log(userRoles.size);
Example 2: Unique Categories with Set
const categories = new Set();
function addCategory(category) {
categories.add(category);
}
function removeCategory(category) {
categories.delete(category);
}
function listCategories() {
return Array.from(categories);
}
// Add categories
addCategory("javascript");
addCategory("webdev");
addCategory("javascript"); // Ignored
addCategory("node.js");
console.log(listCategories()); // ['javascript', 'webdev', 'node.js']
Example 3: Cache with Map
const apiCache = new Map();
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
async function fetchWithCache(url) {
// Check if cached
if (apiCache.has(url)) {
const cached = apiCache.get(url);
if (Date.now() - cached.timestamp < CACHE_DURATION) {
console.log("From cache");
return cached.data;
} else {
apiCache.delete(url); // Expired
}
}
// Fetch new data
console.log("Fetching from API");
const response = await fetch(url);
const data = await response.json();
// Cache it
apiCache.set(url, {
data,
timestamp: Date.now()
});
return data;
}
Example 4: Unique Visitor Tracking with Set
const visitedPages = new Map();
function trackVisit(userId, pageId) {
if (!visitedPages.has(pageId)) {
visitedPages.set(pageId, new Set());
}
visitedPages.get(pageId).add(userId);
}
function getUniqueVisitors(pageId) {
if (visitedPages.has(pageId)) {
return visitedPages.get(pageId).size;
}
return 0;
}
// Track visits
trackVisit("user1", "page-a");
trackVisit("user1", "page-a"); // Same user
trackVisit("user2", "page-a");
trackVisit("user3", "page-a");
console.log(getUniqueVisitors("page-a")); // 3 (unique users)
Practice Assignment
1. Create a Map-based user store:
// Create Map to store users with userId as key
// Add three users
// Find a user
// Update a user
// Delete a user
// Show total users
2. Use Set to remove duplicates:
// Given array of tags with duplicates
// Create Set from array
// Convert back to array
// Show unique tags
3. Build a permission system with Set:
// Create Set of allowed permissions
// Create function to check permission
// Test with valid and invalid permissions
4. Cache implementation with Map:
// Create cache Map
// Implement cache function that checks before computing
// Add same value twice, show it's only computed once
5. Visitor tracking with Map and Set:
// Track which users visited which pages
// Use Map for pages, Set for unique users
// Show unique visitor count per page
Quick Recap
Map is a collection of key-value pairs, better than objects for complex keys.
Set is a collection of unique values, automatically removes duplicates.
Map accepts any data type as keys: strings, numbers, objects, functions.
Object converts all keys to strings or symbols.
Map has a
.sizeproperty, objects needObject.keys().length.Map iterates directly with
.forEach()orfor...of.Objects need
Object.keys()orfor...inloop.Map is faster for frequent additions and deletions.
Map is optimized for key-value storage operations.
Set automatically removes duplicate values.
Array allows duplicates, Set doesn't.
Set has instant membership checking with
.has().Array checking with
.includes()is slower.Array has
.map(),.filter(),.reduce()methods.Set needs spread operator
[...set]to use array methods.Map is perfect for caching, sessions, user data.
Set is perfect for unique values, permissions, tags.
Convert Array to Set with
new Set(array)to remove duplicates.Convert Set to Array with
[...set]for array methods.Objects are for simple JSON data, Maps for complex key-value logic.
Arrays are for lists and sequences, Sets for unique values.
Map and Set are powerful tools for clean, efficient data storage.
If you enjoyed this article, check out my other blogs on this profile. Connect with me: LinkedIn | GitHub | X (Twitter)



