Map and Set Revisited
In Chapter 02, we introduced Map and Set as alternatives to objects and arrays. Now that you are familiar with arrow functions, iteration, and the spread operator, let’s look at these collections more closely.
Iterating Over Maps
Maps maintain insertion order and provide several ways to iterate over their contents.
Using for…of
const userRoles = new Map([
["alice", "admin"],
["bob", "editor"],
["charlie", "viewer"],
]);
// Iterate over entries (default)
for (const [user, role] of userRoles) {
console.log(`${user}: ${role}`);
}
// Iterate over keys only
for (const user of userRoles.keys()) {
console.log(user);
}
// Iterate over values only
for (const role of userRoles.values()) {
console.log(role);
}
Using forEach
const scores = new Map([
["Alice", 95],
["Bob", 87],
["Charlie", 92],
]);
scores.forEach((score, name) => {
console.log(`${name} scored ${score}`);
});
The entries() Method
The entries() method returns an iterator of [key, value] pairs:
const map = new Map([
["a", 1],
["b", 2],
]);
const entries = map.entries();
console.log(entries.next().value); // ["a", 1]
console.log(entries.next().value); // ["b", 2]
Iterating Over Sets
Sets also maintain insertion order and support similar iteration patterns.
const colors = new Set(["red", "green", "blue"]);
// for...of
for (const color of colors) {
console.log(color);
}
// forEach
colors.forEach((color) => {
console.log(color);
});
Sets also have keys(), values(), and entries() methods. Since Sets only have values (no keys), keys() and values() return the same iterator, and entries() returns [value, value] pairs for consistency with Map.
Converting Between Collections and Arrays
We can convert between collections and arrays with the spread operator or Array.from().
Map to Array
const map = new Map([
["name", "Alice"],
["age", 30],
]);
// Spread into array of entries
const entries = [...map];
console.log(entries); // [["name", "Alice"], ["age", 30]]
// Get just keys or values
const keys = [...map.keys()]; // ["name", "age"]
const values = [...map.values()]; // ["Alice", 30]
Set to Array
const set = new Set([1, 2, 3]);
// Using spread
const arr1 = [...set]; // [1, 2, 3]
// Using Array.from
const arr2 = Array.from(set); // [1, 2, 3]
Array to Set (Remove Duplicates)
const numbers = [1, 2, 2, 3, 3, 3, 4];
const unique = [...new Set(numbers)];
console.log(unique); // [1, 2, 3, 4]
Object to Map
const obj = { name: "Alice", age: 30 };
const map = new Map(Object.entries(obj));
console.log(map.get("name")); // "Alice"
Map to Object
const map = new Map([
["name", "Alice"],
["age", 30],
]);
const obj = Object.fromEntries(map);
console.log(obj); // { name: "Alice", age: 30 }
Set Operations
Sets work well for mathematical set operations. Here are the common ones:
Union
Combine all elements from both sets:
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
const union = new Set([...a, ...b]);
console.log([...union]); // [1, 2, 3, 4]
Intersection
Elements that exist in both sets:
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
const intersection = new Set([...a].filter((x) => b.has(x)));
console.log([...intersection]); // [2, 3]
Difference
Elements in the first set but not in the second:
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
const difference = new Set([...a].filter((x) => !b.has(x)));
console.log([...difference]); // [1]
Symmetric Difference
Elements in either set but not in both:
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
const symDiff = new Set([...a, ...b].filter((x) => !(a.has(x) && b.has(x))));
console.log([...symDiff]); // [1, 4]
Practical Example
const subscribedUsers = new Set(["alice", "bob", "charlie"]);
const activeUsers = new Set(["bob", "diana", "eve"]);
// Users who are subscribed AND active
const engagedUsers = new Set(
[...subscribedUsers].filter((u) => activeUsers.has(u)),
);
console.log([...engagedUsers]); // ["bob"]
// Users who are subscribed but NOT active (churned)
const churnedUsers = new Set(
[...subscribedUsers].filter((u) => !activeUsers.has(u)),
);
console.log([...churnedUsers]); // ["alice", "charlie"]