The prerequisite for this article is you already know about arrays and objects in JavaScript (JS). If you want to learn about these, here are links I found interesting: Arrays, Objects.
The Set and Map data structures were introduced in ES6. Therefore, browser compatibility is really good and these are Baseline Widely available features as well.
I like to think of a Set like an array and a Map like an object.
Set - array
Map - object
Set
A set is a list of unique items, sort of an array that contains unique items.
Set v/s Array
A set can only contain unique elements.
A set needs to be instantiated before using it, i.e. new Set().
A set comes with its own methods: add, has, delete, clear, etc (view all methods).
When to use Set
We can use a set to remove duplicate elements in an array.
let userIds = ["001", "002", "003", "001", "003", "001"];
let uniqueUserIds = new Set(userIds);
console.log(uniqueUserIds); // Set(3) ["001", "002", "003"]
userIds = [...uniqueUserIds];
console.log(userIds); // ["001", "002", "003"]
Another example where sets might be useful is whenever we need to store a list of unique items and we want to be able to remove items easily, i.e. without having to splice like when using an array.
let userIds = new Set(["001", "002", "003", "004"]);
userIds.delete("003");
console.log(userIds); // Set(3) [ "001", "002", "004" ]
One less common use case is using mathematical set theory concepts like intersection, union, etc.
let attendeeIds = new Set(["001", "002", "003", "004", "005"]);
let verifiedUserIds = new Set(["002", "003", "005", "008"]);
let verifiedAttendeeIds = attendeeIds.intersection(verifiedUserIds);
console.log(verifiedAttendeeIds); // Set(3) ["002", "003", "005"]
When not to use Set
Anytime there's a need to store duplicate elements, that's when we know we can't use sets.
Sets don't work with JSON. We first need to convert a set to an array then stringify it to JSON.
We also don't have all array features/methods available on sets (also true the other way around). So, choose wisely.
Map
A map is a collection of key-value pairs, similar to an object.
Map v/s Object
A map can contain both primitive and object keys. An object can only have primitive keys.
A map needs to be instantiated before using it, i.e. new Map().
A map comes with its own methods: set, get, has, delete, clear, etc (view all methods).
A map is iterable. An object is not, i.e. we need to use Object.entries / Object.keys / Object.values.
A map retains its insertion order. An object's order is not always guaranteed (read more about this).
When to use Map
If we want to make sure that we're looping through an object-like structure in the insertion order, we need to use a map.
let usersObj = {
aa1: { name: "Alice" },
2: { name: "Bob" },
};
for (let el of Object.entries(usersObj)) {
console.log(el);
} // Bob is displayed before Alice
let usersMap = new Map([
["aa1", { name: "Alice" }],
[2, { name: "Bob" }],
]);
for (let el of usersMap) {
console.log(el);
} // Alice is displayed before Bob
We have to use maps if we need non-primitive keys.
let alice = {
id: "001",
name: "Alice",
};
let bob = {
id: "002",
name: "Bob",
};
let userItems = new Map([
[alice, ["watch", "laptop", "airpods"]],
[bob, ["sunglasses", "watch"]],
]);
userItems.delete(bob);
console.log(userItems); // Map(1) {id: "001", name: "Alice"} => Array(3)
Another reason to use maps is they are generally more performant than objects if we need to manipulate their contents frequently.
let allProducts = new Map([
["k1", { name: "Ketchup" }],
["m2", { name: "Mayo" }],
["m3", { name: "Mustard" }],
]);
let cart = new Map();
// add products k1 & m3 to cart
cart.set("k1", allProducts.get("k1"));
cart.set("m3", allProducts.get("m3"));
// remove product m3 from cart
cart.delete("m3");
// display added products
for (let [id, product] of cart) {
console.log(id, product);
} // k1 -> Object {name: "Ketchup"}
When not to use Map
If we need to store static data, e.g. a project's configuration settings, objects are more efficient.
Maps don't work with JSON. We first need to convert a map to an object then stringify it to JSON.