Map & Set

The Course
•
5 min read

Choose the question before the container

An array represents an ordered sequence. A Set represents unique values: new Set(["a", "a"]) has one member. Use add, has, delete, and size to manage membership. A Set of objects compares object identity, not matching ids; store ids when that is the rule you care about.

A Map associates keys with values. new Map() creates one; set stores a key/value pair and get reads it. has distinguishes a missing key from a stored undefined value. Both Map and Set preserve insertion order. Updating an existing key does not move it to the end.

Map with a capital M is the keyed collection constructor. It is different from the lowercase array .map() method, which transforms array items. A Set can be converted to an array with [...ids], yielding its values in insertion order.

For a small UI, an array plus some is often clear enough. Use a Set when you repeatedly need membership, or a Map when you repeatedly need a record by id. The important decision is not which syntax looks advanced: it is what duplicates mean. Here a repeated id replaces the previous record’s value but keeps the first key position.

Map and Set are not directly represented as keyed collections by JSON.stringify. Convert to a deliberate array representation before saving data; the final app keeps an array of selected books in memory. The optional storage extension serializes that array explicitly; selecting a book does not persist it across a reload.

Predict and trace

Write the output before running. Follow the values through each call; if your prediction differs, identify the first step that surprised you.

Predict, then run JavaScript
const seen = new Set(["js", "web", "js"]);

console.log(seen.size);
console.log(seen.has("web"));

const byId = new Map();

byId.set("js", { title: "Old" });
byId.set("js", { title: "Revised" });
console.log(byId.size);
console.log(byId.get("js").title);
Check your prediction
2
true
1
Revised

new constructs a collection. The second set replaces the value for js, rather than adding a second js entry.

Choose membership or lookup deliberately

A Set answers whether a value is present. A Map associates a key with another value. Both use identity for object keys, so two separately created records with equal-looking fields are not automatically the same member. For domain identity, store the stable id rather than the entire record.

Map.get alone cannot distinguish a missing key from an explicitly stored undefined. Use has when that difference matters. Think about the question the collection must answer before replacing a simple array with another structure.

Choose membership or lookup deliberately: trace JavaScript
const records = new Set([{ id: "a" }, { id: "a" }]);
const ids = new Set(["a", "a"]);

console.log(records.size);
console.log(ids.size);
Check your prediction
2
1

The record objects have different identities; the string ids are equal values. Deduplicating records by object identity would not enforce unique domain ids.

Choose membership or lookup deliberately: contrast JavaScript
const values = new Map();

values.set("known", undefined);
console.log(values.get("known"));
console.log(values.get("missing"));
console.log(values.has("known"), values.has("missing"));
Check your prediction
undefined
undefined
true false

The lookups look alike, but membership differs. Choose whether undefined is permitted data before deciding that a missing get result is a failure.

Try the rule on new inputs

Try updating an existing key and inspect size and iteration order. Then implement duplicate-id detection with a Set containing string ids. The runtime collection does not choose a domain identity policy for you.

Build it yourself

Exercise

Map & Set: practise

Write uniqueIds(books), preserving the first-seen order of ids. Return an array. Print js, web for a list with a duplicate id, then 0 for an empty result length.

Your working space JavaScript
const books = [{ id: "js" }, { id: "web" }, { id: "js" }];
Hint 1: the idea

A Set of ids removes duplicates; a Set of records would not.

Hint 2: a first step

Create the Set, add each book.id, then spread it into an array.

Show one solution
function uniqueIds(books) {
  const ids = new Set();

  for (const book of books) {
    ids.add(book.id);
  }

  return [...ids];
}

const books = [{ id: "js" }, { id: "web" }, { id: "js" }];

console.log(uniqueIds(books).join(", "));
console.log(uniqueIds([]).length);
js, web
0

Try identical-looking objects inside a Set directly and compare the size with a Set of their ids. Explain which duplicate rule you need.

Test a changed requirement

Try identical-looking objects inside a Set directly and compare the size with a Set of their ids. Explain which duplicate rule you need.

Explain before moving on

When would an array remain the clearest choice? Why does get alone not distinguish every missing-key case?

Was this article helpful?

Your response is saved on this device.