Ресурсы: Документация Первая половина статьи Страница учебника
Map ('мэпы') - коллекции, или карты.
В объектах зачастую в качестве свойств используются строки:
Код
const obj = {
name: 'Alex',
age: 22
}
В данном случае, к примеру, свойство
name является строкой, хоть и записано без кавычек, это всё равно строка.
Что же будет, если в качестве ключа передать не строку, а к примеру число:
Код
const obj = {
4: 'Alex',
age: 22
}
А произойдёт то, что 4 превратится в строку и в этом можно убедиться, если вывести в консоль самый первый ключ нашего объекта
Код
console.log(typeof(Object.keys(obj)[0])); // string
Но если в качестве ключа мы попробуем поставить объект, то получим ошибку.
Но бывают ситуации, когда вместо строк в качестве ключей нам нужны другие типы данных.
К примеру, у нас есть список магазинов торговой сети, каждый из них содержит определённый перечень товаров и на каждый из них выделяется определённый бюджет:
Код
const shops = [
{rice: 500},
{oil: 200},
{bread: 50}
]
К каждому из этих объектов (один объект - это один магазин) нужно добавить его бюджет, таким образом, чтобы сформировались пары магазин - бюджет.
Чтобы создать новую карту:
Код
const map = new Map();
Созданная новая карта изначально пустая и её нужно заполнить.
В качестве ключей в "мэпах" можно использовать массивы, объекты, функции и т.д.
По типу данных "мэпы" - это всё те же объекты, но со своими специфическими методами.
Метод set()
Синтаксис этого метода:
Код
map.set(ключ, значение);
Применительно к нашим магазинам:
Код
map.set(shops[0], 5000);
map.set(shops[1], 15000);
map.set(shops[2], 25000);
Или тоже самое, но цепочкой:
Код
map.set(shops[0], 5000).set(shops[1], 15000).set(shops[2], 25000);
Или, как вариант, для удобства читаемости:
Код
map.set(shops[0], 5000)
.set(shops[1], 15000)
.set(shops[2], 25000);
Работа цепочки возможна благодаря тому, что каждый раз, когда отрабатывает звено цепочки, обратно возвращается объект
map Если сейчас вывести в консоль содержимое нашей карты:
То увидим:
Цитата
Map(3) {
{ rice: 500 } => 5000,
{ oil: 200 } => 15000,
{ bread: 50 } => 25000
}
Мы видим что это объект, у которого свойства (ключи) также являются объектами
Цифры бюджетов магазинов могут приходить из каких-то таблиц, либо баз данных
Код
const budget = [5000, 15000, 25000];
И тогда нам нужно соединить две структуры: массив с магазинами и массив с бюджетами, для этого мы можем использовать обычный цикл, либо метод
forEach():
Код
shops.forEach((shop, i) => {
map.set(shop, budget[i]);
})
В аргумент
shop при переборе по очереди будут попадать каждый из трёх объектов, содержащихся в массиве
shops, при этом
i - это порядковый номер каждого из элементов массива.
Если сейчас вывести в консоль содержимое карты, то получим тот же результат, что и до этого.
Работа с картами
Код
map.get(shops[0]); // 5000
map.get(key) - возвращает значение по ключу или
undefined, когда ключ
key отсутствует
Проверка на наличие какого-то ключа в карте:
Код
map.has(shops[0]); // true
map.has(key) - вернёт
true, если ключ
key в коллекции есть, иначе
false Удалить пару "ключ-значение":
Полностью очистить карту от всех элементов:
Узнать текущее количество элементов карты:
Код
map.size; // это свойство
В консоли карта выглядит как объект с объектами, но на самом деле это массив массивов!
Убедимся в этом, добавив в качестве аргумента первое начальное значение для магазинов. Это будет начальное значение при создании карты, затем добавятся остальные с помощью
forEach() Код
const map = new Map([
[{paper: 400}, 8000]
]);
в консоли получаем ожидаемый результат
Цитата
Map(4) {
{ paper: 400 } => 8000,
{ rice: 500 } => 5000,
{ oil: 200 } => 15000,
{ bread: 50 } => 25000
}
Методы перебора карты
map.keys() - возвращает итерируемый объект по ключам, пример:
Код
for (let shop of map.keys()) {
console.log(shop);
}
Результат в консоли:
Цитата
{paper: 400}
{rice: 500}
{oil: 200}
{bread: 50}
Пример №2 : можно получить список товаров всех магазинов.
Создадим для начала переменную с пустым массивом:
Чтобы записать в этот массив все товары, мы можем сделать так:
Код
for (let shop of map.keys()) {
goods.push(Object.keys(shop)[0]);
}
console.log(goods);
Результат в консоли:
Цитата
[ 'paper', 'rice', 'oil', 'bread' ]
Почему именно такая запись?
Код
Object.keys(shop)[0];
Потому, что если записать так
то в консоли будет массив с массивами
Код
[ ['paper'], ['rice'], ['oil'], ['bread'] ]
поэтому, чтобы из каждого массива вытащить его элемент, мы и добавляем его индекс [0]
Всё дело в том, что
Object.keys() возвращает массив из перечисляемых свойств объекта, соответственно:
Код
Object.keys({paper: 400})
вернёт
По аналогии:
Код
Object.keys({rice: 500})
вернёт
И так далее.
Нам же нужен один массив со списком товаров, поэтому из каждого возвращенного с помощью
Object.keys() массива мы вынимаем его элемент с помощью его индекса [0].
Второй способ позволяет получить вместо ключей значения:
Код
for (let price of map.values()) {
console.log(price);
}
В консоли мы получим бюджеты каждого из магазинов:
Цитата
8000
5000
15000
25000
Третий способ позволяет получить массив с массивами, в каждом из которых первый элемент это объект с магазином, а второй - его бюджет.
Код
for (let price of map.entries()) {
console.log(price);
}
Результат в консоли:
Цитата
[ { paper: 400 }, 8000 ]
[ { rice: 500 }, 5000 ]
[ { oil: 200 }, 15000 ]
[ { bread: 50 }, 25000 ]
Часто эти массивы сразу же деструктуризируют, чтобы иметь возможность вывести элементы массивов по отдельности или как то их использовать по отдельности:
Код
for (let [shop, price] of map.entries()) {
console.log(price, shop);
}
И вот результат:
Цитата
8000 { paper: 400 }
5000 { rice: 500 }
15000 { oil: 200 }
25000 { bread: 50 }
Четвёртый способ перебрать карту - это иcпользовать метод
forEach() Код
map.forEach((value, key, map) => {
console.log(key, value);
});
И результат:
Цитата
{ paper: 400 } 8000
{ rice: 500 } 5000
{ oil: 200 } 15000
{ bread: 50 } 25000
Как сделать карту из объекта
Мы можем использовать
Object.entries() для создания карты из имеющегося объекта:
Код
const user = {
name: 'Alex',
surname: 'Smith',
birthday: '20/04/1993',
showMyPublicData: function() {
console.log(`${this.name} ${this.surname}`);
}
}
const userMap = new Map(Object.entries(user));
console.log(userMap);
И в консоли мы получим карту, созданную из объекта
Цитата
Map(4) {
'name' => 'Alex',
'surname' => 'Smith',
'birthday' => '20/04/1993',
'showMyPublicData' => [Function: showMyPublicData]
}
Как создать из карты объект
Метод
Object.fromEntries() преобразует список пар "ключ-значение" в объект
Код
const newUserObj = Object.fromEntries(userMap);
Еще пример:
Код
const entries = new Map([
['foo', 'bar'],
['baz', 42]
]);
const obj = Object.fromEntries(entries);
console.log(obj);
Цитата
{ foo: 'bar', baz: 42 }
Главные отличия карт от объектов
1. У карт ключи могут быть чем угодно: массивами, объектами, функциями, цифрами и т.п. У объектов ключами могут быть только строки
2. Порядок свойств в картах всегда такой, какой мы его добавляли. У объектов нет четкого порядка относительно того, когда было добавлено свойство. Например, если свойство в объект добавляется динамически, оно может быть подставлено в любое место объекта.
3. При создании пустой карты в ней ничего не будет содержаться, в том числе каких-то наследуемых свойств через прототип, а в пустом объекте они есть.
4. Карты легко перебирать и для этого есть много способов.
5. Размеры карты легко получить через свойство
size, с объектом же требуется сначала его трансформация в массив, чтобы затем получить его длину.
Добавлять комментарии могут только зарегистрированные пользователи.