JavaScript Set and Map
Master collection structures using Set and Map, understand key differences, and implement dynamic data lookups.
TL;DR
- 01Use
Setto store unique value collections and eliminate duplicates. - 02Use
Mapto match key-value pairs using any key type. - 03Query
sizeand iterate directly using standardfor-ofloops.
Tips
- 01Deduplicate an array instantly by wrapping it in a
Setand spreading it back. - 02Initialize a new
Mapdirectly from objects using the staticObject.entries()conversion method.
Warnings
- 01Remember that object keys in
Mapcollections are compared using strict reference identity matches. - 02Standard
JSON.stringify()serialization does not natively supportSetorMapcollections.
Set Basics
Set initializationCreates a new Set from an iterable, automatically filtering out duplicate values.
const numbers = new Set([1, 2, 2, 3]);
console.log(numbers); // Set { 1, 2, 3 }add()Adds a new unique value to the Set collection and returns the Set.
const colors = new Set();
colors.add("red").add("blue");has()Checks if a specific value exists in the Set using constant time lookup.
const exists = colors.has("red"); // truedelete() and `clear()`Removes individual items or deletes all elements from the Set collection.
colors.delete("red");
colors.clear();Map Basics
Map initializationCreates a Map storing key-value pairs, maintaining insertion order of keys.
const config = new Map([
["timeout", 5000],
["retries", 3]
]);set()Inserts or updates a value for a specific key in the Map.
const user = new Map();
user.set("name", "Alice");get()Retrieves the value associated with a specific key, returning undefined if missing.
const timeout = config.get("timeout"); // 5000has() checkVerifies if a key is present in the Map collection without reading it.
const hasKey = config.has("timeout"); // trueSet vs Object
Type constraintsSet preserves variable types, while object keys are coerced to strings.
const set = new Set([1, "1"]); // Set { 1, "1" }
const obj = {};
obj[1] = "num";
obj["1"] = "str"; // overrides obj[1]Unique storageSet filters duplicates natively, while objects require manual checks to prevent overwrite.
const set = new Set([5, 5, 5]);
console.log(set.size); // 1Map vs Object
Key typesMap allows objects and functions as keys, whereas objects coerce keys to strings.
const map = new Map();
const keyObj = { id: 1 };
map.set(keyObj, "metadata");
console.log(map.get(keyObj)); // "metadata"Size propertiesMap counts elements directly via size, whereas objects require key array length.
const map = new Map([["a", 1]]);
console.log(map.size); // 1
const obj = { a: 1 };
console.log(Object.keys(obj).length); // 1Iteration and Conversion
Set iterationLoops through Set values directly using a standard for-of loop.
const numbers = new Set([1, 2, 3]);
for (const num of numbers) {
console.log(num);
}Map iterationDestructures entries into key-value pairs during iteration loops.
const user = new Map([["name", "Alice"]]);
for (const [k, v] of user) {
console.log(k, v);
}Spread conversionsConverts collection elements back into standard arrays using the spread operator.
const set = new Set([1, 2]);
const arr = [...set]; // [1, 2]In Practice
Processes raw login attempts to return unique user lists and trace login frequencies using Set and Map collections.
- 01Deduplicate the list of raw usernames by instantiating a
Setcollection. - 02Spread the unique set items back into a standard username array.
- 03Create a new
Mapinstance to log individual user frequency totals. - 04Iterate through usernames, retrieving previous counts or defaulting to zero.
- 05Increment and update the login total for each user in the map.
function analyzeLogins(usernames) {
const uniqueUsers = [...new Set(usernames)];
const loginCounts = new Map();
for (const user of usernames) {
const count = loginCounts.get(user) ?? 0;
loginCounts.set(user, count + 1);
}
return {
uniqueUsers,
loginCounts
};
}FAQ
Use the has() method, which performs instant lookup check queries. This method is much faster than checking arrays with includes(). Set checks take constant time regardless of size.
Yes, you can use any value including objects and arrays as keys in a Map. These keys are matched by reference. Two separate empty objects are treated as two distinct keys.
Use the array spread operator within the Set constructor. For example, write new Set([...setA, ...setB]). This automatically merges all elements while discarding duplicate entries.
Choose Map when keys are not strings or when insertion order must be preserved. A Map is also optimized for frequent additions and removals. Plain objects work better for simple static configs.
Convert entries by spreading the collection: [...myMap]. This returns an array of key-value pairs. To get only keys or values, use [...myMap.keys()] or [...myMap.values()].