Понимание карты и набора в JavaScript

Понимание карты и набора в JavaScript

18-10-2020 09:35:59
В JavaScript разработчики часто тратят много времени на выбор правильной структуры данных. Это связано с тем, что выбор правильной структуры данных может упростить манипулирование этими данными в дальнейшем, экономя время и облегчая понимание кода. Двумя преобладающими структурами данных для хранения коллекций данных являются Objects и Arrays (тип объекта). Разработчики используют объекты для хранения пар ключ / значение и массивы для хранения индексированных списков. Однако, чтобы предоставить разработчикам больше гибкости, спецификация ECMAScript 2015 представила два новых типа итерируемых объектов: Карты, которые являются упорядоченными коллекциями пар ключ / значение, и Наборы, которые являются коллекциями уникальных значений.

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

Карты


Карта - это набор пар ключ / значение, которые могут использовать любой тип данных в качестве ключа и поддерживать порядок его записей. Карты имеют элементы обоих объектов (уникальная коллекция пар ключ / значение) и массивов (упорядоченная коллекция), но концептуально они больше похожи на объекты. Это связано с тем, что, хотя размер и порядок записей сохраняются в виде массива, сами записи являются парами ключ / значение, такими как объекты.

Карты могут быть инициализированы с помощью new Map()синтаксиса:

const map = new Map()

Это дает нам пустую карту:

Map(0) {}


Добавление значений на карту


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

Следующее добавляет три пары ключ / значение к map:

map.set('firstName', 'Luke')
map.set('lastName', 'Skywalker')
map.set('occupation', 'Jedi Knight')
Здесь мы начинаем видеть, как у Карт есть элементы как Объектов, так и Массивов. Как и у массива, у нас есть коллекция с нулевым индексом, и мы также можем видеть, сколько элементов на карте по умолчанию. Карты используют =>синтаксис для обозначения пар ключ / значение как key => value:

Map(3)
0: {"firstName" => "Luke"}
1: {"lastName" => "Skywalker"}
2: {"occupation" => "Jedi Knight"}
Этот пример похож на обычный объект со строковыми ключами, но мы можем использовать любой тип данных в качестве ключа в Map.

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

[ ['key1', 'value1'],
['key2', 'value2'] ]
Используя следующий синтаксис, мы можем воссоздать ту же карту:

const map = new Map([
['firstName', 'Luke'],
['lastName', 'Skywalker'],
['occupation', 'Jedi Knight'],
])
Между прочим, этот синтаксис такой же, как результат вызова Object.entries()объекта. Это обеспечивает готовый способ преобразования объекта в карту, как показано в следующем блоке кода:

const luke = {
firstName: 'Luke',
lastName: 'Skywalker',
occupation: 'Jedi Knight',
}

const map = new Map(Object.entries(luke))
Кроме того, вы можете превратить карту обратно в объект или массив с помощью одной строки кода.

Следующее преобразует карту в объект:

const obj = Object.fromEntries(map)
Это приведет к следующему значению obj:

{firstName: "Luke", lastName: "Skywalker", occupation: "Jedi Knight"}
Теперь давайте преобразуем карту в массив:

const arr = Array.from(map)
Это приведет к следующему массиву для arr:

[ ['firstName', 'Luke'],
['lastName', 'Skywalker']
['occupation', 'Jedi Knight'] ]

Ключи карты


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

Сначала давайте инициализируем карту нестроковыми ключами:

const map = new Map()

map.set('1', 'String one')
map.set(1, 'This will be overwritten')
map.set(1, 'Number one')
map.set(true, 'A Boolean')

Этот пример переопределит первый ключ 1с последующим, и он будет рассматривать '1'строку и 1число как уникальные ключи:

0: {"1" => "String one"}
1: {1 => "Number one"}
2: {true => "A Boolean"}

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

Например, инициализируйте объект числовым ключом и сравните значение числового 1ключа и строкового "1"ключа:

// Initialize an object with a numerical key
const obj = { 1: 'One' }

// The key is actually a string
obj[1] === obj['1'] // true

Вот почему, если вы попытаетесь использовать объект в качестве ключа, он object Objectвместо этого выведет строку .

В качестве примера создайте объект, а затем используйте его в качестве ключа другого объекта:

// Create an object
const objAsKey = { foo: 'bar' }

// Use this object as the key of another object
const obj = {
[objAsKey]: 'What will happen?',
}

Это приведет к следующему:

{[object Object]: "What will happen?"}
Это не так с картой. Попробуйте создать объект и установить его в качестве ключа карты:

// Create an object
const objAsKey = { foo: 'bar' }

const map = new Map()

// Set this object as the key of a Map
map.set(objAsKey, 'What will happen?')
Элемент keyMap теперь является объектом, который мы создали.

key: {foo: "bar"}
value: "What will happen?"
Следует обратить внимание на одну важную вещь, касающуюся использования объекта или массива в качестве ключа: карта использует ссылку на объект для сравнения на равенство, а не буквальное значение объекта. В JavaScript {} === {}возвращается false, потому что два объекта не являются одинаковыми двумя объектами, несмотря на одинаковое (пустое) значение.

Это означает, что добавление двух уникальных объектов с одинаковым значением создаст карту с двумя записями:

// Add two unique but similar objects as keys to a Map
map.set({}, 'One')
map.set({}, 'Two')
Это приведет к следующему:

Map(2) {{…} => "One", {…} => "Two"}
Но использование одной и той же ссылки на объект дважды приведет к созданию карты с одной записью.

// Add the same exact object twice as keys to a Map
const obj = {}

map.set(obj, 'One')
map.set(obj, 'Two')
Что приведет к следующему:

Map(1) {{…} => "Two"}
Второй set()обновляет тот же самый точный ключ, что и первый, поэтому мы получаем карту, которая имеет только одно значение.

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

Мы можем инициализировать новую карту , чтобы продемонстрировать следующие свойства и методы: delete(), has(), get(), и size.

// Initialize a new Map
const map = new Map([
['animal', 'otter'],
['shape', 'triangle'],
['city', 'New York'],
['country', 'Bulgaria'],
])
Используйте has()метод, чтобы проверить наличие элемента на карте. has()вернет логическое значение.

// Check if a key exists in a Map
map.has('shark') // false
map.has('country') // true
Используйте get()метод для получения значения по ключу.

// Get an item from a Map
map.get('animal') // "otter"
Одно из особых преимуществ Карт по сравнению с Объектами заключается в том, что вы можете найти размер Карты в любое время, как вы можете с помощью Массива. Вы можете получить количество элементов на карте с sizeсобственностью. Это включает в себя меньше шагов, чем преобразование объекта в массив для определения длины.

// Get the count of items in a Map
map.size // 4
Используйте delete()метод для удаления элемента с карты по ключу. Метод вернет логическое значение - trueесли элемент существовал и был удален, и falseесли он не соответствует ни одному элементу.

// Delete an item from a Map by key
map.delete('city') // true
Это приведет к следующей карте:

Map(3) {"animal" => "otter", "shape" => "triangle", "country" => "Bulgaria"}
Наконец, карту можно очистить от всех значений с помощью map.clear().

// Empty a Map
map.clear()
Это даст:

Map(0) {}

Ключи, значения и записи для карт


Объекты могут извлекать ключи, значения и записи, используя свойства Objectконструктора. Карты, с другой стороны, имеют методы-прототипы, которые позволяют нам напрямую получать ключи, значения и записи экземпляра Map.

keys(), values()И entries()методы вернет MapIterator, который похож на массив в том , что вы можете использовать , for...ofчтобы перебрать значение.

Вот еще один пример карты, которую мы можем использовать для демонстрации этих методов.

const map = new Map([
[1970, 'bell bottoms'],
[1980, 'leg warmers'],
[1990, 'flannel'],
])
keys()Метод возвращает ключи:

map.keys()
MapIterator {1970, 1980, 1990}
values()Метод возвращает значение:

map.values()
MapIterator {"bell bottoms", "leg warmers", "flannel"}
entries()Метод возвращает массив пар ключ / значение:

map.entries()
MapIterator {1970 => "bell bottoms", 1980 => "leg warmers", 1990 => "flannel"}

Итерация с картой


В Map есть встроенный forEachметод, похожий на Array, для встроенной итерации. Однако есть разница в том, что они повторяют. Обратный вызов из карты в forEachПеребирает value, keyи mapсам по себе, в то время как массив версии итерацию через item, indexи arrayсам по себе.

// Map
Map.prototype.forEach((value, key, map) = () => {}

// Array
Array.prototype.forEach((item, index, array) = () => {}
Это большое преимущество для Карт над Объектами, поскольку Объекты должны быть преобразованы с помощью keys(), values()или entries(), и не существует простого способа получить свойства Объекта без его преобразования.

Чтобы продемонстрировать это, давайте пройдемся по нашей карте и зарегистрируем пары ключ / значение на консоли:

// Log the keys and values of the Map with forEach
map.forEach((value, key) => {
console.log(`${key}: ${value}`)
})

Это даст:

1970: bell bottoms
1980: leg warmers
1990: flannel
Поскольку for...ofцикл выполняет итерации по таким элементам, как Map и Array, мы можем получить точно такой же результат, уничтожив массив элементов Map:

// Destructure the key and value out of the Map item
for (const [key, value] of map) {
// Log the keys and values of the Map with for...of
console.log(`${key}: ${value}`)
}

Свойства и методы карты


В следующей таблице приведен список свойств и методов Map для быстрого ознакомления:

Свойства / Методы Описание Возвращает
set(key, value) Добавляет пару ключ / значение на карту Map объект
delete(key) Удаляет пару ключ / значение с карты по ключу логический
get(key) Возвращает значение по ключу значение
has(key) Проверяет наличие элемента на карте по ключу логический
clear() Удаляет все элементы с карты N / A
keys() Возвращает все ключи на карте MapIterator объект
values() Возвращает все значения на карте MapIterator объект
entries() Возвращает все ключи и значения на карте как [key, value] MapIterator объект
forEach() Итерация по карте в порядке вставки N / A
size Возвращает количество элементов на карте номер

Когда использовать карту


Подводя итог, Карты похожи на Объекты в том, что они содержат пары ключ / значение, но Карты имеют несколько преимуществ перед объектами:

Размер - у карт есть sizeсвойство, а у объектов нет встроенного способа получения их размера.
Итерация - карты являются итеративными, а объекты - нет.
Гибкость - Карты могут иметь любой тип данных (примитив или объект) в качестве ключа к значению, в то время как объекты могут иметь только строки.
Упорядоченный - Карты сохраняют свой порядок вставки, тогда как объекты не имеют гарантированного порядка.
Из-за этих факторов, карты являются мощной структурой данных для рассмотрения. Тем не менее, Objects имеет ряд важных преимуществ:

JSON - объекты работают безупречно JSON.parse()и JSON.stringify(), две основные функции для работы с JSON , общий формат данных , что многие API - интерфейсы REST дело.
Работа с одним элементом - Работая с известным значением в объекте, вы можете получить к нему доступ напрямую с помощью ключа без необходимости использования метода, такого как Map get().
Этот список поможет вам решить, является ли карта или объект правильной структурой данных для вашего варианта использования.

Set


Набор - это коллекция уникальных значений. В отличие от карты, набор концептуально больше похож на массив, чем на объект, поскольку представляет собой список значений, а не пары ключ / значение. Однако Set не является заменой для массивов, а скорее является дополнением для обеспечения дополнительной поддержки работы с дублированными данными.

Вы можете инициализировать наборы с помощью new Set()синтаксиса.

const set = new Set()
Это дает нам пустой набор:

Set(0) {}

Предметы могут быть добавлены в набор с помощью add()метода. (Это не следует путать с set()методом, доступным для Map, хотя они похожи.)

// Add items to a Set
set.add('Beethoven')
set.add('Mozart')
set.add('Chopin')

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

set.add('Chopin') // Set will still contain 3 unique values
Примечание . То же сравнение равенства, которое применяется к ключам карты, относится и к элементам набора. Два объекта, которые имеют одинаковое значение, но не имеют одинаковую ссылку, не будут считаться равными.

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

// Initialize a Set from an Array
const set = new Set(['Beethoven', 'Mozart', 'Chopin', 'Chopin'])
Set(3) {"Beethoven", "Mozart", "Chopin"}

И наоборот, набор может быть преобразован в массив с одной строкой кода:

const arr = [...set]
(3) ["Beethoven", "Mozart", "Chopin"]

Набор имеет многие из тех же методов и свойств , как карты, в том числе delete(), has(), clear(), и size.

// Delete an item
set.delete('Beethoven') // true

// Check for the existence of an item
set.has('Beethoven') // false

// Clear a Set
set.clear()

// Check the size of a Set
set.size // 0
Обратите внимание, что Set не имеет доступа к значению по ключу или индексу, например Map.get(key)или arr[index].

Ключи, значения и записи для наборов
Карта и установить оба имеют keys(), values()и entries()методы , которые возвращают итератор. Однако, хотя каждый из этих методов имеет отдельное назначение в Map, наборы не имеют ключей, и поэтому ключи являются псевдонимами для значений. Это означает, что keys()и values()оба будут возвращать один и тот же итератор и entries()будут возвращать значение дважды. Лучше всего использовать только values()с Set, так как два других метода существуют для согласованности и перекрестной совместимости с Map.

const set = new Set([1, 2, 3])
// Get the values of a set
set.values()
SetIterator {1, 2, 3}

Итерация с множеством


Как и в Map, Set имеет встроенный forEach()метод. Поскольку наборы не имеют ключей, первый и второй параметр forEach()обратного вызова возвращают одно и то же значение, поэтому для него нет варианта использования вне совместимости с Map. Параметры forEach()являются (value, key, set).

Оба forEach()и for...ofмогут быть использованы на Set. Сначала давайте посмотрим на forEach()итерацию:

const set = new Set(['hi', 'hello', 'good day'])

// Iterate a Set with forEach
set.forEach(value => console.log(value))
Тогда мы можем написать for...ofверсию:

// Iterate a Set with for...of
for (const value of set) {
console.log(value)
}

Обе эти стратегии приведут к следующему:

hi
hello
good day

Установить свойства и методы


В следующей таблице приведен список свойств и методов Set для быстрого ознакомления:

Свойства / Методы Описание Возвращает
add(value) Добавляет новый элемент в набор Set объект
delete(value) Удаляет указанный элемент из набора логический
has() Проверяет наличие предмета в наборе логический
clear() Удаляет все предметы из набора N / A
keys() Возвращает все значения в наборе (так же, как values()) SetIterator объект
values() Возвращает все значения в наборе (так же, как keys()) SetIterator объект
entries() Возвращает все значения в наборе как [value, value] SetIterator объект
forEach() Перебирает Set в порядке вставки N / A
size Возвращает количество предметов в наборе номер

Когда использовать Set


Набор является полезным дополнением к вашему инструментарию JavaScript, особенно для работы с дублирующимися значениями в данных.

В одной строке мы можем создать новый массив без повторяющихся значений из массива, который имеет повторяющиеся значения.

const uniqueArray = [...new Set([1, 1, 2, 2, 2, 3])] // (3) [1, 2, 3]
Это даст:

(3) [1, 2, 3]
Набор может использоваться для нахождения объединения, пересечения и разницы между двумя наборами данных. Однако Массивы имеют значительное преимущество по сравнению с наборами для дополнительных манипуляций с данными из - за sort(), map(), filter()и reduce()методы, а также прямую совместимости с JSONметодами.

Вывод


Из этой статьи вы узнали, что Map - это набор упорядоченных пар ключ / значение, а Set - набор уникальных значений. Обе эти структуры данных добавляют дополнительные возможности в JavaScript и упрощают общие задачи, такие как определение длины коллекции пары ключ / значение и удаление дублирующих элементов из набора данных соответственно. С другой стороны, объекты и массивы традиционно используются для хранения данных и манипулирования ими в JavaScript и имеют прямую совместимость с JSON, что делает их наиболее важными структурами данных, особенно для работы с API-интерфейсами REST. Карты и наборы в первую очередь полезны в качестве поддержки структур данных для объектов и массивов.


САМОЕ ОБСУЖДАЕМОЕ

...
Титан в воздухе
18-10-2020 09:35:58
Это не самолет – это Мрия!!!...
...
Лучшие бюджетные ноутбуки на 2020 год
18-10-2020 09:35:59
Как выбрать лучший ноутбук в 2020 году...
...
Технологические тенденции в 2020 году
18-10-2020 09:35:59
Технологи будущего уже сегодня...
...
Самостоятельная поездка автомобиля под управлением искусственного интеллекта
18-10-2020 09:35:58
Самый далекий перезд без водителя в истории искуственного интеллекта....
...
Ford Bronco наконец дебютирует 9 июля
18-10-2020 09:35:58
После задержек, связанных с коронавирусом, у долгожданной Бронко Форда официально объявлена ​​дата....
...
Tesla Semi готова к «массовому производству»
18-10-2020 09:35:58
Но генеральный директор не указал точные сроки начала производства электрического грузовика....
...
25 самых продаваемых легковых автомобилей, грузовиков и внедорожников 2020 года (пока)
18-10-2020 09:35:58
Хотя пандемия коронавируса привела к хаосу в продажах автомобилей, мы подсчитали рейтинг самых продаваемых в первом квартале....
...
Электрический Mustang
18-10-2020 09:35:58
Ford представляет электрический Mustang с «потрясающим» ускорением...
...
Cамые большие дизайнерские моменты 2018 года
18-10-2020 09:35:59
Мы попросили дизайнеров рассказать нам, что они считают самой важной вещью, которая произошла в отрасли в этом году....
...
Airtable
18-10-2020 09:35:59
Простая в использовании система управления реляционными базами данных...

НАШИ РЕКОМЕНДАЦИИ

Toyota Supra в 2021 году
Toyota Supra в 2021 году
Toyota Supra 2020 года не получит дооснащения, чтобы соответствовать увеличению мощности в 2021 году...
9 различных вариантов использования console log
9 различных вариантов использования console log
Каждый из нас использовал console.logдля отладки больше, чем нам хотелось бы признать....
Расслабление, снятие стресса и развитие сознания
Расслабление, снятие стресса и развитие сознания
Иногда в жизни бывают дни.......
Послушай других и сделай наооборот
Послушай других и сделай наооборот
Основатель Tesla и SpaceX воплотил в жизнь одну идею, противоречащую общепринятому мнению, и это помогло ему заработать миллиарды....
Красный флаг или работа не Вашей мечты.
Красный флаг или работа не Вашей мечты.
В последнее время развелось (были всегда) много организаций на рынке - которые надо обходить стороной....


ИНТЕРЕСНОЕ

Понимание карты и набора в JavaScript
Понимание карты и набора в JavaScript
Эта статья была изначально написана для DigitalOcean ....
Lazareth Wazuma от Феррари
Lazareth Wazuma от Феррари
Lazareth Wazuma V8F Quad – Engine By Ferrari...
20 самых важных секретов настоящих отношений
20 самых важных секретов настоящих отношений
Не простые отношения между женщинами и мужчинами...
Работа в Швеции
Работа в Швеции
Компании в Швеции переходят на 6-часовые рабочие дни и добиваются удивительных результатов...


ЛУЧШИЕ РЕЙТИНГИ

Набор массы
Набор массы
Базовые принципы для новичков
Ежедневные 15-минутные прогулки способны кардинально изменить ваше тело
Ежедневные 15-минутные прогулки способны кардинально изменить ваше тело
Всем известно, как положительно влияют на организм...
Правила для наращивания мышечной массы
Правила для наращивания мышечной массы
Зная интенсивность физических упражнений...
Раскачать грудь
Раскачать грудь
Обычно грудные растут хорошо у тех...

АКТУАЛЬНОЕ

Будущее уже с нами Galaxy Fold
CEO продвижение
Отношения с мужчинами
Раздевалка
Лишь плохие начальники ожидают от своих подчиненных постоянной занятости
Как научиться читать быстрее
Выбирай того, кто ежедневно пишет тебе «С добрым утром»
США скрывают правду о пришельцах
Свечение от ракеты SpaceX американцы приняли за НЛО
Путешествие из Австрии в Италию

ЧИТАЙТЕ ТАКЖЕ

18-10-2020 09:35:59 (120052)
Какую одежду носят манхэттенские модницы летом
Возможно эта новость тебе еще неизвестна
18-10-2020 09:35:59 (120050)
Время сгибаемых смартфонов еще не пришло
Эксперт по технологиям издания Mashable Стэн Шредер написал колонку...
18-10-2020 09:35:59 (120049)
Успешные стартапы, которые начинали как сторонние проекты
Apple, Facebook, Google, SpaceX ...
18-10-2020 09:35:59 (120051)
Надо стараться быть с теми, кто к нам хорошо относится
Маленький гимназист очень плохо учился...
18-10-2020 09:35:59 (120044)
Стопроцентная диета для похудения или питание наоборот
Сделай все наоборот....
18-10-2020 09:35:59 (120046)
Невероятная 12-месячная трансформацией тела
Звезда фитнеса из Сиднея Софи Аллен рассказывает о своей трансформации..