Руководство JavaScript Map and Set: как использовать новые встроенные классы

Руководство JavaScript Map and Set Программирование и разработка

В прошлом, когда дело касалось коллекций, JavaScript был ограничен. В то время как другие языки предлагают списки, наборы, ассоциативные карты и словари, JavaScript предлагает только массивы. Программистам на JavaScript пришлось найти обходной путь для создания наборов или карт, что затрудняло поддержку кода.

Теперь, с ES6, JavaScript предлагает новые встроенные классы для наборов и карт, которые значительно упрощают поддержку программирования. В этом руководстве мы подробно познакомим вас с отображением и настройкой, а также с примерами кода, вариантами использования и практическими упражнениями. Это руководство идеально подходит для разработчиков JavaScript, которые хотят усовершенствовать свои навыки работы с JavaScript.

Что есть map?

До ES6 разработчики JavaScript использовали объекты для сопоставления ключей со значениями. Однако использование объекта в качестве карты имеет свои ограничения. Например:

  • Не существует надежного способа перебора ключей, и keys()метод преобразует поля в строки, что приводит к конфликту ключей.
  • Нет простого способа добавить новые ключи и значения

ES6 представил несколько новых встроенных классов , включая называемый тип коллекцииMap , который может содержать пары ключ-значение любого типа. В отличие от объектного подхода, новый объект Map может запоминать порядок вставки ключей.

Проще говоря, JavaScript Map- это ассоциативный набор различных ключей и значений. И ключи, и значения могут быть любым примитивом или объектом. Это важная структура данных, которая может быть полезна для многих целей.

Примечание: A WeakMapпохож на Map, но все ключи a WeakMapявляются объектами.

Для создания нового Mapмы используем следующий синтаксис:

let map = new Map([iterable]);

Давайте применим это на практике на более сложном примере. Ниже у нас есть карта, в которой имена являются ключами, а оценки — значениями.

‘use strict’;
//START:DEFINE
const scores =
  new Map([[‘Sara’, 12], [‘Bob’, 11], [‘Jill’, 15], [‘Bruce’, 14]]);
scores.set(‘Jake’, 14);
console.log(scores.size);
//END:DEFINE
  • scores Карта была инициализирована с именами и оценки. Начальные данные могут быть любыми итеративными с парой ключей и значений.
  • Мы добавляем ключ и значение на карту, используя set()метод (строка 7)
  • Чтобы выяснить, сколько ключей в настоящее время находится на карте, мы используем свойство size (строка 9).
Читайте также:  Вызов функции C++ по указателю

Примечание: Map.has(key) выше будет возвращено логическое значение, чтобы указать, находится ли элемент, связанный с указанным ключом, на карте.

Как пользоваться картой

Когда мы узнаем, как создавать карты с помощью JavaScript, мы сможем многое сделать с ними.

Перебирать карты

Во-первых, давайте узнаем об итерации с помощью карт. Мы можем использовать 3 метода:

  • map.keys(): возвращает итерацию для ключей
  • map.entries(): возвращает итерацию для записей [key, value]
  • map.values(): возвращает итерацию для значений

Мы можем перебирать коллекцию ключей и значений с помощью entries()метода, который возвращает итерацию, поэтому мы можем использовать улучшенное for loopвместе с деструктуризацией.

Например, ниже мы извлекаем имя и оценку для каждой пары ключ-значение:

‘use strict’;
//START:DEFINE
const scores =
  new Map([[‘Sara’, 12], [‘Bob’, 11], [‘Jill’, 15], [‘Bruce’, 14]]);
scores.set(‘Jake’, 14);
//END:DEFINE
for(const [name, score] of scores.entries()) {
  console.log(`${name} : ${score}`);
}

Мы также можем использовать forEachметод, который является внутренним итератором.

‘use strict’;
//START:DEFINE
const scores =
  new Map([[‘Sara’, 12], [‘Bob’, 11], [‘Jill’, 15], [‘Bruce’, 14]]);
scores.set(‘Jake’, 14);
//END:DEFINE
scores.forEach((score, name) => console.log(`${name} : ${score}`));

Первый параметр, который получает функция, — это значение ключа, который появляется как второй параметр. Тот же forEach()метод можно использовать для перебора только значений:

‘use strict’;
//START:DEFINE
const scores =
  new Map([[‘Sara’, 12], [‘Bob’, 11], [‘Jill’, 15], [‘Bruce’, 14]]);
scores.set(‘Jake’, 14);
//END:DEFINE
scores.forEach(score => console.log(score));

Если вы получите только один параметр, это будет значение, а если вы получите два параметра, то это будет значение и ключ для каждой пары ключ-значение.

Инициализировать карту с итерируемым объектом

Вы также можете передать конструктору итерируемый объект Map():

let userRoles = new Map([
    [sarah, ‘admin’],
    [bob, ‘editor’],
    [jill, ‘subscriber’]
]);

Получить элемент с карты по ключу

Мы можем получить элементы с карты по ключу с помощью get()метода:

Но если вы передадите ключ, которого нет на этой карте, он вернет undefined.

userRoles.get(sarah); // admin

Но если вы передадите ключ, которого нет на этой карте, он вернет undefined.

let foo = {name: 'Foo'};
userRoles.get(foo); //undefined

Получить количество элементов на карте

Мы можем использовать sizeсвойство, чтобы получить количество элементов на наших картах.

console.log(userRoles.size); // 3

Преобразование ключей или значений карты в массив

Иногда вам может понадобиться работать с массивом вместо итерируемого объекта. Мы можем использовать оператор распространения, чтобы преобразовать ключи для каждого элемента в новый массив.

var keys = [...userRoles.keys()];
console.log(keys);

Этот фрагмент кода преобразует значения элементов в массив:

var roles = [...userRoles.values()];
console.log(roles);

Другие важные методы карты

  • clear(): удаляет элементы из объекта карты.
  • map.set(key, value): сохраняет значение по ключу
  • delete(key): удаляет определенный элемент (указанный ключом)
  • set(key, value): устанавливает значение ключа и возвращает объект карты. Может быть связан с другими методами.
  • forEach(callback[, thisArg]): вызывает обратный вызов для каждой пары «ключ-значение» в порядке вставки. thisArgПараметр является необязательным и устанавливает thisзначение для каждого обратного вызова.
  • has(key): возвращает, trueесли значение, связанное с ключом, существует, в противном случае false.
  • keys(): возвращает новый итератор с ключами для элементов в порядке вставки.
  • values(): возвращает новый объект итератора со значениями для каждого элемента в порядке вставки.
  • map.size: возвращает текущее количество элементов

Что есть set?

Set- еще одна новая коллекция, представленная ES6. ArrayКласс JavaScript может работать с упорядоченным набором данных, но не так хорошо с неупорядоченными коллекциями или когда значения хранятся в коллекции являются уникальными. Вот почему появился JavaScript Set.

A set- это уникальный набор примитивов и объектов, дублирование которых не допускается. Мы можем либо создать пустой набор и добавить объекты, либо инициализировать набор содержимым итерации (например, массива).

Давайте рассмотрим это на примере. Ниже у нас есть набор имен с пятью значениями. Одно из значений не входит в набор из-за дублирования.

‘use strict’;
//START:CREATE
const names = new Set([‘Jack’, ‘Jill’, ‘Jake’, ‘Jack’, ‘Sara’]);
//END:CREATE
//START:SIZE
console.log(names.size);
//END:SIZE

Мы можем добавлять элементы в существующий набор, как показано ниже:

names.add('Matt');

add()Метод возвращает поток Set, который является полезным для цепных операций, таких как более звонков add()или других методов Set:

names.add('Kate')
  .add('Kara');

Как использовать set

Как только мы выясним, как создавать наборы, с ними легко работать. Сначала посмотрим на встроенные функции для наборов:

  • has(): чтобы проверить, есть ли в наборе определенный элемент.
  • clear(): очистить существующий набор или удалить существующий элемент с помощью delete()метода.
  • keys(): получить все значения из набора
  • entries(): для перебора Set с использованием расширенного цикла for, как показано ниже:
‘use strict’;
//START:CREATE
const names = new Set([‘Jack’, ‘Jill’, ‘Jake’, ‘Jack’, ‘Sara’]);
//END:CREATE
//START:ADD
names.add(‘Mike’);
//END:ADD
//START:ADD2
names.add(‘Kate’)
  .add(‘Kara’);
//END:ADD2
console.log(names.has(‘Brad’));
console.log(names.entries());
console.log(names.keys());
console.log(names.values());
//START:ITERATE1
for(const name of names) {
  console.log(name);
}
//END:ITERATE1

filter/ mapс наборами

Set еще не предлагает таких методов, как filter()и map(), но мы можем создать массив из набора и использовать методы функционального стиля для этого нового массива.

Например, ниже мы используем методы filter(), map()и, forEach()чтобы выбрать только имена, начинающиеся с, Jа затем преобразовать их в верхний регистр.

‘use strict’;
//START:CREATE
const names = new Set([‘Jack’, ‘Jill’, ‘Jake’, ‘Jack’, ‘Sara’]);
//END:CREATE
//START:ADD
names.add(‘Mike’);
//END:ADD
//START:ADD2
names.add(‘Kate’)
  .add(‘Kara’);
//END:ADD2
//START:FILTER
[…names].filter(name => name.startsWith(‘J’))
  .map(name => name.toUpperCase())
  .forEach(name => console.log(name));
//END:FILTER

Get the size of a Set

Используйте sizeсвойство объекта Set, чтобы вернуть его размер.

let size = chars.size;
console.log(size);//  3

Удалить элементы из набора

Чтобы удалить элемент из набора, используйте delete()метод.

chars.delete('f');
console.log(chars); // Set {"a", "b", "c", "d", "e"}

А чтобы удалить все элементы набора, используйте clear()метод:

chars.clear();
console.log(chars); // Set{}

Вызов функции обратного вызова для каждого элемента

Чтобы вызвать обратный вызов для каждого элемента вашего набора, используйте forEach()метод.

roles.forEach(role => console.log(role.toUpperCase()));

Другие важные методы Set

  • new Set(iterable): создает набор.
  • set.add(value): добавляет заданное значение и возвращает набор
  • set.has(value): возвращается, trueесли значение существует в наборе, в противном случае возвращается false.
  • set.clear(): удаляет все из набора

Практическое упражнение с map

Чтобы закрепить ваше обучение, давайте выполним практическое упражнение с картой на JavaScript. Используйте Mapдля получения желаемого результата, как указано ниже. При создании объекта createTodo()он должен возвращать элемент карты.

Входные звонки Выход
console.log(todo.get(‘learn JavaScript’)); Выполнено
console.log(todo.get(‘write elegant code’)); работа в процессе
console.log(todo.get(‘automate tests’)); работа в процессе
console.log(completedCount(todo)); 1

Ниже приводится решение этой проблемы. Сначала попробуйте сами.

‘use strict’;
const createTodo = function() {
  const todo = new Map();
  return todo;
};
const completedCount = function(map) {
  return;
};
const todo = createTodo(); //Returns a Map

Разбивка решения

Начнем с создания элемента карты. MapОбъект todoсоздается на линии 4 , используя встроенный класс. Вы можете видеть, что объект карты todoвызывается Map.get()с разными ключами для получения их значений. Это означает, что нам нужно добавить все ключи и значения.

Мы добавляем новый элемент todoс ключами и соответствующими значениями. В строках 5-7 мы добавляем новые элементы, устанавливая значения для ключей.

Для completedCount()мы определяем новую функцию с параметром объекта карты. Функция вернет количество выполненных задач. Итак, по сути, мы фильтруем все значения элементов в объекте карты, чтобы получить элементы со значением, равным done(см. Строку 14).

В строке 15 свойство length используется для подсчета количества специальных элементов.

Что изучать дальше

Map и set — ценные дополнения к JavaScript, они сделают ваш код более чистым и легким в обслуживании. Теперь, когда у вас есть четкое понимание карты и набора, вы готовы заняться другими функциями, добавленными в ES6 и не только.

Вот несколько концепций, которые следует рассмотреть при модернизации вашего JavaScript:

  • Async и Await ( обещания )
  • Метапрограммирование
  • Объектные литералы
  • Стрелочные функции
Оцените статью
bestprogrammer.ru
Добавить комментарий