Ads and ad measurement. Disabled until you allow it.
ABOUT SITE
All open site tabs
JavaScript · Syntax · Intermediate
Map
10 tasks
Learn the Map data structure in JavaScript — a key-value collection that accepts any type as a key, preserves insertion order, and provides efficient add, get, and delete operations.
Quick topic start and explanations before exercises (exercises below):
`Map` is a key-value collection, similar to a plain object, but with important differences that make it better in several situations.
**Creating a Map and core methods**
```javascript
const m = new Map();
m.set('name', 'Alice'); // add or update an entry
m.set(42, 'answer'); // number as key — works fine
m.set(true, 'yes'); // boolean as key — works fine
m.get('name'); // "Alice"
m.get(42); // "answer"
m.has('name'); // true
m.has('phone'); // false
m.size; // 3 (property, no parentheses)
m.delete('name'); // removes entry, returns true if existed
m.clear(); // removes all entries
```
You can also initialize from an array of `[key, value]` pairs:
```javascript
const scores = new Map([
['Alice', 95],
['Bob', 87],
]);
```
**How Map differs from Object**
Object only accepts strings and symbols as keys. Map accepts anything — numbers, objects, other Maps, even functions. This matters when you need to use non-string data as a lookup key.
Object doesn't have a built-in `size` — you need `Object.keys(obj).length`. Map has `.size` directly.
Map preserves insertion order for all key types. Object does too for string keys in modern engines, but not reliably for integer-like strings.
Map is directly iterable with `for...of`. Object requires `Object.entries()` or similar.
**When to use Map vs Object**
Use Map when:
- Keys are not strings (numbers, objects, symbols)
- You need `.size` without extra code
- You're adding and deleting entries frequently (Map is optimized for mutations)
- You need a guaranteed iteration order across all key types
Keep using Object when:
- You have string/symbol keys and don't need the above
- You need JSON serialization — `JSON.stringify` ignores Map entries
- You're writing config or data you know at write time (object literals are more readable)
Three patterns cover most real-world Map usage: iterating over entries, converting between Map and Object, and using Map as a frequency counter.
**Iterating**
```javascript
const m = new Map([['a', 1], ['b', 2], ['c', 3]]);
for (const [key, value] of m) {
console.log(key, value); // most common form
}
for (const [key, value] of m.entries()) {
console.log(key, value); // identical to the above
}
for (const key of m.keys()) { console.log(key); }
for (const val of m.values()) { console.log(val); }
m.forEach((value, key) => {
console.log(key, value); // note: value comes first, key second
});
```
`for...of` destructures each entry directly. `forEach` has reversed parameter order compared to array's `forEach` — a frequent source of confusion.
**Map as a frequency counter**
```javascript
const text = "hello";
const freq = new Map();
for (const ch of text) {
freq.set(ch, (freq.get(ch) ?? 0) + 1);
}
// Map { 'h'=>1, 'e'=>1, 'l'=>2, 'o'=>1 }
```
`freq.get(ch) ?? 0` reads the current count or falls back to 0 if the character isn't yet in the Map. Then `+ 1` increments it. This pattern works for any counter — words, events, categories.
**Converting between Map, Object, and Array**
```javascript
// Object → Map
const obj = { a: 1, b: 2 };
const m = new Map(Object.entries(obj));
// Map → Object
const back = Object.fromEntries(m);
// Array of pairs → Map
const m2 = new Map([['x', 10], ['y', 20]]);
// Map → Array of pairs
const pairs = [...m.entries()];
// Merging two Maps (later key wins on collision)
const m1 = new Map([['a', 1], ['b', 2]]);
const m3 = new Map([['b', 99], ['c', 3]]);
const merged = new Map([...m1, ...m3]);
// b → 99 (m3 overwrites m1)
```
Spread `...` converts a Map to an iterable of pairs — the same format the Map constructor accepts. This is how both the merge and the array-of-pairs conversion work.
Quick lookup for Map methods and a comparison with plain Object.
**Methods and properties**
`new Map()` — empty map
`new Map(iterable)` — from `[[key, val], ...]` pairs
`map.set(key, val)` — add/update entry; returns the map (chainable)
`map.get(key)` — value, or undefined if key is missing
`map.has(key)` — true/false
`map.delete(key)` — remove one entry; returns true if it existed
`map.clear()` — remove all entries
`map.size` — number of entries (property, no parentheses)
`map.keys()` — iterator over keys
`map.values()` — iterator over values
`map.entries()` — iterator over [key, value] pairs
`map.forEach(fn)` — `fn(value, key, map)` for each entry
**Iteration**
```javascript
for (const [key, val] of map) { } // most common
for (const [key, val] of map.entries()) { } // same
for (const key of map.keys()) { }
for (const val of map.values()) { }
map.forEach((val, key) => { }); // value first, key second
```
**Map vs Object**
Key types: Map accepts any value; Object only strings and symbols.
Size: `map.size` vs `Object.keys(obj).length`.
Iteration: Map is directly iterable; Object needs `Object.entries()`.
JSON: `JSON.stringify` skips Map — convert to Object first.
Prototype: Map has no inherited properties; Object may inherit from prototype.
Performance: Map is optimized for frequent add/delete; Object for static shape.
**Common conversions**
Object → Map: `new Map(Object.entries(obj))`
Map → Object: `Object.fromEntries(map)`
Map → Array of pairs: `[...map.entries()]`
Merge: `new Map([...m1, ...m2])` — m2 wins on key collision
Create a Map with three entries: `"name"` → `"Alice"`, `"age"` → `30`, `"city"` → `"Kyiv"`.
Then print: the value for `"name"`, whether `"age"` exists, whether `"phone"` exists.
// your code here
Solution
const m = new Map();
m.set("name", "Alice");
m.set("age", 30);
m.set("city", "Kyiv");
console.log(m.get("name"));
console.log(m.has("age"));
console.log(m.has("phone"));
Count how many times each word appears in `text` using a Map.
Print the Map.
let text = "the cat sat on the mat the cat";
// your code here
Solution
let text = "the cat sat on the mat the cat";
const freq = new Map();
for (const word of text.split(" ")) {
freq.set(word, (freq.get(word) ?? 0) + 1);
}
console.log(freq);
Create a phone book Map with three contacts: `"Alice"` → `"+380501234567"`, `"Bob"` → `"+380679876543"`, `"Charlie"` → `"+380931112233"`.
Look up `"Bob"` — if found print the number, otherwise print `"Not found"`.
Write a function `cachedSquare(n)` that returns `n * n` but stores results in a Map so each number is computed only once.
Call it three times: with `5`, `5` again, and `7`. Print each result and the cache size at the end.
const cache = new Map();
function cachedSquare(n) {
// your code here
}
console.log(cachedSquare(5));
console.log(cachedSquare(5));
console.log(cachedSquare(7));
console.log(cache.size);
Solution
const cache = new Map();
function cachedSquare(n) {
if (!cache.has(n)) {
cache.set(n, n * n);
}
return cache.get(n);
}
console.log(cachedSquare(5));
console.log(cachedSquare(5));
console.log(cachedSquare(7));
console.log(cache.size);
Find the country in `capitals` whose capital is `"Berlin"`. Print the country name, or `"Not found"` if missing.
const capitals = new Map([["France", "Paris"], ["Germany", "Berlin"], ["Ukraine", "Kyiv"]]);
// your code here
Solution
const capitals = new Map([["France", "Paris"], ["Germany", "Berlin"], ["Ukraine", "Kyiv"]]);
let result = "Not found";
for (const [country, capital] of capitals) {
if (capital === "Berlin") {
result = country;
break;
}
}
console.log(result);
const users = [
{ name: "Alice", role: "admin" },
{ name: "Bob", role: "user" },
{ name: "Charlie", role: "admin" },
{ name: "Dave", role: "user" },
];
const groups = new Map();
for (const user of users) {
if (!groups.has(user.role)) {
groups.set(user.role, []);
}
groups.get(user.role).push(user.name);
}
console.log(groups);
No split tab
Cookie preferences
We use necessary cookies to run the site. With your permission, we can also save your site preferences and use analytics and advertising cookies to understand usage and support the project.
Open tools in tabs.Exercises, IDE tools, and trainers stay available as site tabs.
Switch without losing context.Move between explanations, code, and utilities while keeping your place.
Use the sidebar as your map.The left panels hold navigation, settings, files, libraries, and tool controls.
PythonJavaScriptSQLite
One IDE, three practical modes
Python in the browser.Run small scripts, try libraries, and practice API requests without installing anything.
JavaScript for quick experiments.Test browser-friendly code and compare ideas next to your learning materials.
SQLite for data practice.Open the database explorer to inspect tables, write queries, and learn SQL workflows locally.
TopicIDE
Work side by side with split tabs
Keep instructions visible.Open an exercise or reference page beside the IDE instead of jumping back and forth.
Compare tools while you learn.Place regex checks, explanations, and code experiments next to each other when the task needs it.
Close the split when you are done.The workspace returns to a single focused tab, and your open site tabs remain available.
Code Typing Trainer
Or plain text
This trainer is designed for a physical keyboard.Open this section on a laptop or desktop with a wide screen. Touch typing practice will not work correctly on a phone.
Speed: 0 chars/min
0 words/min
Best speed (60s): 0 chars/min
0 words/min
Errors: 0
Total time: 0.0 s
To practice touch typing, avoid looking at your physical keyboard.