LMX
BlogSelectedWorkSponsorsAbout
Command Palette

Search for a command to run...

Blog

Interviewer: Explain Set and Map

LMXMar 8, 202412 min read#JavaScript#Interview Notes

A practical overview of JavaScript Set and Map, including their core concepts, common APIs, real-world use cases, and the related WeakSet and WeakMap types.

My inner monologue after hearing this question:

I memorized all the impressive advanced topics, so why are we starting with the basics? I am interviewing for a senior role—shouldn't you ask about project tuning, first-screen performance, or build optimization? This interviewer is not following the script. All that fancy interview trivia I memorized is going to waste. Better luck next time.

Set and Map

Concepts

Why did ES6 introduce Set and Map? Why do languages such as Java also provide these structures and variations of them?

The official interview-style answer is:

ES6 added Set and Map to provide more powerful and flexible data operations for increasingly complex programming requirements.

What is a Set?

A Set is a collection data structure.

What is a Map?

A Map is a dictionary data structure.

What are collections and dictionaries?

A collection consists of unordered, related, non-duplicate values.

A dictionary consists of elements whose distinct key fields identify them.

Both store unique entries. A Set conceptually stores [value, value], while a dictionary stores [key, value].

Basic Usage

Initializing a Set

  • new Set() creates an empty Set.
  • new Set(iterable) creates a Set from every value in an iterable.

Pay attention to the second form: the input must be iterable.

const set1 = new Set(); // Empty Set
const set2 = new Set([1, 2, 3]); // Three numeric values
const set3 = new Set("abc"); // Three characters
const set4 = new Set(
  new Map([
    ["a", 1],
    ["b", 2],
  ]),
); // Two entry arrays

Using Set

The common operations are:

  • add(value): Add a value. Set uses add, not an array's push.
  • delete(value): Delete a value.
  • has(value): Return whether the value exists.
  • clear(): Remove every member.

A Set's member count is its size, not length.

Set provides several iteration methods:

  • values(): Return an iterator over values.
  • keys(): An alias of values().
  • entries(): Return an iterator over [value, value] pairs.
  • forEach(): Invoke a callback for each member.
  • for...of: Iterate over all members.

Examples matter more than reciting API names. Run them in a console until the behavior becomes familiar. AI may help us code day to day, but interviews still expect us to understand the fundamentals ourselves.

const set1 = new Set();
const set2 = new Set([1, 2, 3]);
const set3 = new Set("abc");
const set4 = new Set(
  new Map([
    ["a", 1],
    ["b", 2],
  ]),
);

set2.forEach((value) => {
  console.log(value);
});

for (const value of set2) {
  console.log(value);
}

// values() returns an iterator.
const iterator1 = set3.values();
for (const value of iterator1) {
  console.log(value);
}

// Each item returned by entries() is [value, value].
const iterator2 = set2.entries();
for (const entry of iterator2) {
  console.log(entry);
}

Initializing a Map

A Map is an ordered list of key-value pairs. Keys and values may be any type, including primitives and objects. Map is the constructor used to create it.

Characteristics:

  • Key-value pairs: Both key and value can have any type.
  • Insertion order: Iteration follows insertion order.
  • Unique keys: Adding the same key again replaces its value.
  • Efficient operations: Lookup, insertion, and deletion are generally efficient.

Use new Map() for an empty Map or new Map(iterable) to initialize it from key-value pairs.

const map1 = new Map();
const map2 = new Map([
  ["a", 1],
  ["b", 2],
]);

// A Set containing valid entry arrays is also iterable input for Map.
const map3 = new Map(
  new Set([
    ["a", 1],
    ["b", 2],
  ]),
);

Using Map

The familiar CRUD operations are:

  • map.set(key, value): Add or update a key-value pair. Map uses set, not Set's add.
  • map.delete(key): Remove an entry.
  • map.has(key): Check whether a key exists.
  • map.get(key): Get the value for a key. Set has no corresponding get method.

Like Set, Map exposes its entry count through size.

For iteration:

  • forEach() visits every key-value pair.
  • for...of iterates entries.
  • keys() returns an iterator over keys.
  • values() returns an iterator over values.
  • entries() returns an iterator over key-value pairs.
const map1 = new Map([["a", 1]]);
const map2 = new Map([
  ["a", 1],
  ["b", 2],
]);
const map3 = new Map(
  new Set([
    ["a", 1],
    ["b", 2],
  ]),
);

map1.forEach((value, key) => {
  console.log(key, value);
});

for (const [key, value] of map2) {
  console.log(key, value);
}

for (const key of map3.keys()) {
  console.log(key);
}
for (const value of map3.values()) {
  console.log(value);
}
for (const [key, value] of map3.entries()) {
  console.log(key, value);
}

Practice these examples in the console. There is no shame in typing them several times; repetition turns memorized facts into usable knowledge.

Common Set Use Cases

Removing Duplicates

A Set cannot contain duplicate values, which makes array deduplication concise:

[...new Set([1, 2, 3, 3, 1, 2])];

Intersection

const set1 = new Set([1, 2, 3]);
const set2 = new Set([2, 3, 4]);
const intersection = new Set([...set1].filter((x) => set2.has(x)));

Union

const set1 = new Set([1, 2, 3]);
const set2 = new Set([2, 3, 4]);
const union = new Set([...set1, ...set2]);

Difference

const set1 = new Set([1, 2, 3]);
const set2 = new Set([2, 3, 4]);
const difference = new Set([...set1].filter((x) => !set2.has(x)));

Equality

Compare sizes and ensure every value from one Set exists in the other:

const set1 = new Set([1, 2, 3]);
const set2 = new Set([1, 2, 3]);

console.log(set1.size === set2.size && [...set1].every((x) => set2.has(x))); // true

JavaScript Set does not provide a built-in equals() method.

Common Map Use Cases

Conversion

Map conversion is common and worth memorizing:

  • Map to array: [...map] or Array.from(map).
  • Array to Map: new Map(iterable).
  • Map to object: Object.fromEntries(map).
  • Object to Map: new Map(Object.entries(obj)).
const arr = [...map1]; // [["a", 1]]
const map4 = new Map([
  ["a", 1],
  ["b", 2],
]);
const obj = Object.fromEntries(map4); // { a: 1, b: 2 }
const map5 = new Map(Object.entries(obj));

Modeling a Dictionary

const dictionary = new Map([
  ["apple", "a fruit"],
  ["banana", "a fruit"],
  ["cat", "an animal"],
]);

console.log(dictionary.get("apple")); // "a fruit"

Caching Data

const cache = new Map();

function getData(key) {
  if (cache.has(key)) {
    return cache.get(key);
  }

  const data = fetch(key);
  cache.set(key, data);
  return data;
}

const data = getData("https://www.example.com");

Deduplicating Objects

Use a Map keyed by id to retain one object per identifier:

const objects = [
  { id: 1, name: "John" },
  { id: 2, name: "Mary" },
  { id: 1, name: "Alice" },
];

const uniqueObjects = new Map();
for (const object of objects) {
  if (!uniqueObjects.has(object.id)) {
    uniqueObjects.set(object.id, object);
  }
}

console.log([...uniqueObjects.values()]);

Counting Occurrences

const words = ["a", "b", "c", "a", "b"];
const wordCounts = new Map();

for (const word of words) {
  if (wordCounts.has(word)) {
    wordCounts.set(word, wordCounts.get(word) + 1);
  } else {
    wordCounts.set(word, 1);
  }
}

console.log(wordCounts); // Map { "a" => 2, "b" => 2, "c" => 1 }

Implementing an LRU Cache

Map's insertion order makes it useful for a least-recently-used cache:

class LRUCache {
  constructor(capacity) {
    this.capacity = capacity;
    this.cache = new Map();
  }

  get(key) {
    if (!this.cache.has(key)) return undefined;
    const value = this.cache.get(key);
    this.cache.delete(key);
    this.cache.set(key, value);
    return value;
  }

  set(key, value) {
    if (this.cache.has(key)) this.cache.delete(key);
    if (this.cache.size === this.capacity) {
      const oldestKey = this.cache.keys().next().value;
      this.cache.delete(oldestKey);
    }
    this.cache.set(key, value);
  }
}

const cache = new LRUCache(2);
cache.set("a", 1);
cache.set("b", 2);
console.log(cache.get("a")); // 1
cache.set("c", 3);
console.log(cache.get("b")); // undefined

WeakSet and WeakMap

WeakSet stores weakly held objects. Referencing an object from a WeakSet does not prevent garbage collection. It is not enumerable, does not expose size, and supports add, delete, and has.

WeakMap stores key-value pairs whose keys are weakly held objects. A WeakMap reference does not prevent a key object from being collected. It is also not enumerable and supports set, delete, has, and get.

Both are useful for associating metadata with object lifetimes without accidentally keeping those objects alive.

Summary

Advanced topics cannot compensate for missing fundamentals. The more confidently you bluff, the harder it becomes to recover when an interviewer asks a basic question.

The dramatic inner monologues and interviewer commentary above are fictional—you know the style by now.

Hello, brother. Welcome to New World. I am the Elevator Warrior—leave a like and save the article, or I am coming for you!

Discussion

Support the author
Previous post

Intermediate Front-End Interview Compilation - Middle Volume

Next post

Intermediate Front-End Interview Compilation - Middle Volume

LMX BlogWeb · TypeScript · Vue · Node.js
Crafted by
@LMXZQQ
Build
unavailable
Date
2026-10-30
Articles
29
Deployed on
Nginx
Source code
GitHub
License
MIT License
Typeface
Geist
Stack
  • next@16.4.3
  • react@19.3.1
  • @base-ui/react@1.8.0
  • shadcn@4.12.0
  • tailwindcss@4.3.3
Analytics
  • OpenPanel
  • Google Analytics
For agents
  • llms.txt
  • index.md
Inspired by
  1. Tailwind CSS
  2. shadcn/ui
  3. Vercel
  4. Apple
  5. Evil Charts
  6. Devouring Details
  7. Skiper UI
  8. Making Software
  9. shadcncraft
Approved by
静水流深 / LMX
1602
Command Palette

Search for a command to run...