Статистика использования. Отключена, пока вы её не разрешите.
Реклама и измерение рекламы. Отключены, пока вы их не разрешите.
О САЙТЕ
Все открытые вкладки сайта
JavaScript · Синтаксис · Промежуточный
Map
10 задач
Изучи структуру данных Map в JavaScript — коллекцию ключ-значение, принимающую любой тип в качестве ключа, сохраняющую порядок вставки и обеспечивающую эффективные операции добавления, получения и удаления.
Краткое введение в тему и пояснения перед упражнениями (упражнения ниже):
Map: коллекция ключ-значение с произвольным типом ключа
`Map` — это коллекция ключ-значение, похожая на обычный объект, но с важными отличиями, которые делают её лучшим выбором в определённых ситуациях.
**Создание Map и основные методы**
```javascript
const m = new Map();
m.set('name', 'Alice'); // добавить или обновить запись
m.set(42, 'answer'); // число как ключ — работает
m.set(true, 'yes'); // булево значение как ключ — работает
m.get('name'); // "Alice"
m.get(42); // "answer"
m.has('name'); // true
m.has('phone'); // false
m.size; // 3 (свойство, без скобок)
m.delete('name'); // удаляет запись, возвращает true если существовала
m.clear(); // удаляет все записи
```
Можно также инициализировать из массива пар `[key, value]`:
```javascript
const scores = new Map([
['Alice', 95],
['Bob', 87],
]);
```
**Чем Map отличается от Object**
Object принимает только строки и символы в качестве ключей. Map принимает что угодно — числа, объекты, другие Map, даже функции. Это важно когда нужно использовать не-строковые данные в качестве ключа поиска.
В Object нет встроенного `size` — нужно `Object.keys(obj).length`. В Map есть `.size` напрямую.
Map сохраняет порядок вставки для всех типов ключей. Object тоже для строковых ключей в современных движках, но не гарантированно для ключей похожих на целые числа.
Map напрямую итерируется через `for...of`. Object требует `Object.entries()` или аналогов.
**Когда использовать Map вместо Object**
Выбирай Map когда:
- Ключи не являются строками (числа, объекты, символы)
- Нужен `.size` без лишнего кода
- Часто добавляешь и удаляешь записи (Map оптимизирован для мутаций)
- Нужен гарантированный порядок итерации для всех типов ключей
Оставляй Object когда:
- Есть строковые/символьные ключи и вышеперечисленное не нужно
- Нужна JSON-сериализация — `JSON.stringify` игнорирует записи Map
- Пишешь конфиг или данные известные в момент написания кода (объектные литералы читабельнее)
Три паттерна покрывают большинство реального использования Map: итерация по записям, конвертация между Map и Object, и Map как счётчик частоты.
**Итерация**
```javascript
const m = new Map([['a', 1], ['b', 2], ['c', 3]]);
for (const [key, value] of m) {
console.log(key, value); // наиболее частая форма
}
for (const [key, value] of m.entries()) {
console.log(key, value); // идентично предыдущему
}
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); // внимание: value идёт первым, key вторым
});
```
`for...of` деструктурирует каждую запись напрямую. У `forEach` обратный порядок параметров по сравнению с `forEach` массива — частый источник ошибок.
**Map как счётчик частоты**
```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` читает текущий счётчик или возвращает 0 если символа ещё нет в Map. Затем `+ 1` увеличивает его. Этот паттерн работает для любых счётчиков — слов, событий, категорий.
**Конвертация между Map, Object и Array**
```javascript
// Object → Map
const obj = { a: 1, b: 2 };
const m = new Map(Object.entries(obj));
// Map → Object
const back = Object.fromEntries(m);
// Массив пар → Map
const m2 = new Map([['x', 10], ['y', 20]]);
// Map → Массив пар
const pairs = [...m.entries()];
// Слияние двух Map (при совпадении ключа побеждает последний)
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 перезаписывает m1)
```
Spread `...` превращает Map в итерируемый массив пар — тот же формат что принимает конструктор Map. Именно так работает и слияние, и конвертация в массив пар.
Быстрый справочник методов Map и сравнение с обычным Object.
**Методы и свойства**
`new Map()` — пустая Map
`new Map(iterable)` — из массива пар `[[key, val], ...]`
`map.set(key, val)` — добавить/обновить запись; возвращает map (цепочка)
`map.get(key)` — значение, или undefined если ключа нет
`map.has(key)` — true/false
`map.delete(key)` — удалить запись; возвращает true если существовала
`map.clear()` — удалить все записи
`map.size` — количество записей (свойство, без скобок)
`map.keys()` — итератор ключей
`map.values()` — итератор значений
`map.entries()` — итератор пар [key, value]
`map.forEach(fn)` — `fn(value, key, map)` для каждой записи
**Итерация**
```javascript
for (const [key, val] of map) { } // наиболее частое
for (const [key, val] of map.entries()) { } // то же самое
for (const key of map.keys()) { }
for (const val of map.values()) { }
map.forEach((val, key) => { }); // value первым, key вторым
```
**Map vs Object**
Типы ключей: Map принимает любое значение; Object только строки и символы.
Размер: `map.size` против `Object.keys(obj).length`.
Итерация: Map напрямую итерируется; Object требует `Object.entries()`.
JSON: `JSON.stringify` пропускает Map — конвертируй в Object сначала.
Прототип: Map не имеет унаследованных свойств; Object может наследовать из прототипа.
Производительность: Map оптимизирован для частых добавлений/удалений; Object для статичной формы.
**Частые конвертации**
Object → Map: `new Map(Object.entries(obj))`
Map → Object: `Object.fromEntries(map)`
Map → Массив пар: `[...map.entries()]`
Слияние: `new Map([...m1, ...m2])` — при совпадении ключа m2 побеждает
Создай Map с тремя записями: `"name"` → `"Alice"`, `"age"` → `30`, `"city"` → `"Kyiv"`.
Затем выведи: значение для `"name"`, существует ли `"age"`, существует ли `"phone"`.
// твой код здесь
Решение
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"));
Подсчитай сколько раз каждое слово встречается в `text` с помощью Map.
Выведи Map.
let text = "the cat sat on the mat the cat";
// твой код здесь
Решение
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);
Создай Map телефонной книги с тремя контактами: `"Alice"` → `"+380501234567"`, `"Bob"` → `"+380679876543"`, `"Charlie"` → `"+380931112233"`.
Найди `"Bob"` — если есть — выведи номер, иначе — `"Not found"`.
Напиши функцию `cachedSquare(n)`, которая возвращает `n * n` но хранит результаты в Map чтобы каждое число вычислялось только раз.
Вызови трижды: с `5`, снова `5` и `7`. Выведи каждый результат и размер кеша в конце.
const cache = new Map();
function cachedSquare(n) {
// твой код здесь
}
console.log(cachedSquare(5));
console.log(cachedSquare(5));
console.log(cachedSquare(7));
console.log(cache.size);
Решение
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);
Найди страну в `capitals` чья столица — `"Berlin"`. Выведи название страны, или `"Not found"` если не найдено.
const capitals = new Map([["France", "Paris"], ["Germany", "Berlin"], ["Ukraine", "Kyiv"]]);
// твой код здесь
Решение
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
Настройки cookies
Мы используем необходимые cookies для работы сайта. С вашего разрешения мы также можем сохранять настройки сайта и использовать аналитические и рекламные cookies, чтобы понимать использование сайта и поддерживать развитие проекта.
* Вы всегда можете изменить свой выбор в настройках сайта.
Выберите категории cookies
Настройки аналитики
Можно отключить аналитику использования платформы. Также можно отправить в Google Analytics запрос на удаление данных об использовании этого сайта, связанных с этим браузером.
Учебный workspace
Учитесь, читая, запуская код и решая задачи.
Практикуйте программирование с пояснениями тем, упражнениями, инструментами browser IDE, проверкой regex и тренировкой печати кода в одном workspace.
Открывайте инструменты во вкладках.Упражнения, IDE-инструменты и тренажеры остаются доступными как вкладки сайта.
Переключайтесь без потери контекста.Переходите между пояснениями, кодом и утилитами, сохраняя свое место.
Используйте sidebar как карту.Левые панели содержат навигацию, настройки, файлы, libraries и управление инструментами.
PythonJavaScriptSQLite
Одна IDE, три практичных режима
Python в браузере.Запускайте небольшие скрипты, пробуйте библиотеки и тренируйте API-запросы без установки.
JavaScript для быстрых экспериментов.Проверяйте код для браузера и сравнивайте идеи рядом с учебными материалами.
SQLite для практики с данными.Открывайте обозреватель базы данных, изучайте таблицы, пишите запросы и учитесь SQL локально.
ТемаIDE
Работайте рядом в split tabs
Держите инструкции перед глазами.Откройте упражнение или справочную страницу рядом с IDE, вместо постоянных переключений.
Сравнивайте инструменты во время обучения.Размещайте проверки regex, пояснения и эксперименты с кодом рядом, когда это нужно для задачи.
Закройте split, когда закончите.Workspace вернётся к одной сфокусированной вкладке, а открытые вкладки сайта останутся доступны.
Тренажер слепой печати кода
Или просто текста
Тренажер рассчитан на физическую клавиатуру.Откройте этот раздел на ноутбуке или компьютере с широким экраном. На телефоне тренировка слепой печати не будет корректной.
Скорость: 0 зн/мин
0 слов/мин
Лучшая скорость (60с): 0 зн/мин
0 слов/мин
Ошибки: 0
Общее время: 0.0 с
Для активации режима слепого набора не подсматривайте на физическую клавиатуру.