# 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.

```javascript
// 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

```javascript
// 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

```javascript
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

```javascript
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.

```javascript
// 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

```javascript
// 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

```javascript
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

```javascript
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

```plaintext
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

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
// 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:

```javascript
const obj = {};

console.log(obj.toString);  // Inherited from Object.prototype
```

Maps don't have this baggage:

```javascript
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

```javascript
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:

```javascript
const arr = [1, 2, 3, 4, 4, 5, 5, 5];

console.log(arr.length);  // 8 (includes duplicates)
```

Sets don't allow duplicates:

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
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):

```javascript
const arr = [5, 1, 3, 2, 4];

console.log(arr[0]);  // 5 (original order)
```

Sets maintain insertion order (in modern JS):

```javascript
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:

```javascript
const arr = [1, 2, 3];  // Small array
```

Sets use more memory for small amounts, less for large:

```javascript
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

```plaintext
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:

```javascript
// 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:

```javascript
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:

```javascript
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:

```javascript
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:

```javascript
// 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:

```javascript
// 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:

```javascript
// 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:

```javascript
// 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:

```javascript
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:

```javascript
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:

```javascript
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

```javascript
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

```javascript
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

```javascript
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

```javascript
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:**

```javascript
// 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:**

```javascript
// Given array of tags with duplicates
// Create Set from array
// Convert back to array
// Show unique tags
```

**3. Build a permission system with Set:**

```javascript
// Create Set of allowed permissions
// Create function to check permission
// Test with valid and invalid permissions
```

**4. Cache implementation with Map:**

```javascript
// 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:**

```javascript
// 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 `.size` property, objects need `Object.keys().length`.

- **Map** iterates directly with `.forEach()` or `for...of`.

- **Objects** need `Object.keys()` or `for...in` loop.

- **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](https://linkedin.com/in/rajharsh03) | [GitHub](https://github.com/RajHarsh03) | [X (Twitter)](https://x.com/rajharsh03)
