01. Map
Map
— коллекция для хранения записей вида ключ:значение
. Предпочтительнее использовать вместо объектов, когда нужна структура вида ключ-значение.
Отличия карт от объектов:
В объектах в которых ключами могут быть только строки, в
Map
ключом может быть произвольное значение, в том числе объект или функция.Объект имеет прототипы, что влияет на его ключи. Карты с этой точки зрения выступают как "чистые объекты".
Можно легко получить размер карты, размер объектов много сложнее.
Карта сохраняет пары ключ-значение в порядке их добавления.
Перебор гарантированно осуществляется в порядке вставки.
На картах реализованы символы
Symbol.iterator
Symbol.toStringTag
Symbol.species
Create Map
При создании Map
можно сразу инициализировать списком значений. Аргументом new Map
должен быть итерируемый объект (не обязательно именно массив):
// Create new empty map.
const map = new Map();
// From array of pairs or from any iterable of pairs
const map = new Map([
[1, "one"],
[2, "two"],
[3, "three"] // trailing comma is ignored
]);
const map2 = new Map()
.set(1, "one")
.set(2, "two")
.set(3, "three");
Object.entries()
also lets you set up a Map via an object. This is more concise than using an Array of 2-element Arrays, but keys can only be strings:
let map = new Map(
Object.entries({
one: 1,
two: 2
})
);
Map
API
Map
APIДля сохранения и чтения значений используются методы get
и set
. И ключи и значения сохраняются «как есть», без преобразований типов.
Другие методы:
size
- число записей вMap
.clear()
- удаляет все записи из карты.delete()
- удаляет запись с ключомkey
, возвращаетtrue
, если такая запись была, иначеfalse
.has()
- возвращаетtrue
, если ключ есть, иначеfalse
.get()
- возвращает значение по ключу илиundefined
set()
- ассоциирует значение с ключом и возвращает текущую карту.
let map = new Map();
map.set(1, "Anton").set("2", "Nastya");
map.size; // 2
map.get(1); // Anton
map.get("2"); // Nastya
map.get(2); // undefined
Для проверки значений на эквивалентность используется алгоритм SameValueZero
. Он аналогичен строгому равенству ===
, отличие — в том, что NaN
считается равным NaN
. Поэтому значение NaN
также может быть использовано в качестве ключа.
Map
iteration
Map
iterationДля итерации по map
используется один из трёх методов:
map.keys()
— возвращает итерируемый объект для ключей,map.values()
— возвращает итерируемый объект для значений,map.entries()
— возвращает итерируемый объект для записей[ключ, значение]
, он используется по умолчанию вfor..of
.for..of
- аналогичен вызовуmap.entries()
[...map]
- аналогичен вызову методаmap.entries()
.Карты имеют метод
forEach
, но не имеют методовmap
иfilter
.
const map = new Map().set(false, "no").set(true, "yes");
for (const [key, value] of map.entries()) {
console.log(key, value);
}
Notice that map.values()
and map.entries()
return iterator objects. To put the result into an array, the spread operator ...
is necessary. In a for..of
loop statement the iterator can be used directly.
const map = new Map().set(false, 'no').set(true, 'yes');
[...map.keys()] // [ false, true ]
[...map.values()] // ['no', 'yes']
[...map.entries()] // [[false, 'no'], [true, 'yes']]
Карты можно комбинировать используя spread
операторы в конструкторе:
const combinedMap = new Map([...map1, ...map2])
[...combinedMap] // convert to Array to display
[ [ 1, 'a1' ],
[ 2, 'b2' ],
[ 3, 'c2' ],
[ 4, 'd2' ] ]
К карты не имеют функции map
, но её можно соответствующим образом эмулировать:
let map0 = new Map([
[1, "a"],
[2, "b"],
[3, "c"]
]);
let map1 = new Map( // step 3
[...map0] // step 1
.map(([k, v]) => [k * 2, "_" + v]) // step 2
);
// Resulting Map: {2 -> '_a', 4 -> '_b', 6 -> '_c'}
Аналогичным образом можно эмулировать функцию filter
.
Conversions
Конверсия карты в JSON и обратно:
function mapToJson(map) {
return JSON.stringify([...map]);
}
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
Конверсия карт в объекты возможна только если все ключи карты являются строками:
function mapToObj(map) {
const obj = Object.create(null);
for (const [k, v] of map) {
// We don’t escape the key '__proto__'
// which can cause problems on older engines
obj[k] = v;
}
return obj;
}
function objToMap(obj) {
const map = new Map();
for (const k of Object.keys(obj)) {
map.set(k, obj[k]);
}
return map;
}
Last updated
Was this helpful?