Способы создания набора в JavaScript?
в Eloquent JavaScript, Глава 4, набор значений создается путем создания объекта и хранения значений в качестве имен свойств, присваивая произвольные значения (например, true) в качестве значений свойств. Чтобы проверить, если значение уже содержится в наборе,in оператор используется:
var set = {};
if (!'Tom' in set) {
set.Tom = true;
}
это идиоматический JavaScript? Не будет ли использование массива еще лучше?
var set = [];
if (!'Tom' in set) {
set.push = 'Tom';
}
7 ответов:
наборы теперь доступны в ES2015 (aka ES6, т. е. ECMAScript 6). ES6 является текущим стандартом для JavaScript с июня 2015 года.
ECMAScript 6 имеет набор структур данных, который работает для произвольных значения, быстро и обрабатывает NaN правильно. - Аксель Rauschmayer,изучение ES6
первые два примера из от Axel Rauschmayer-х книги знакомства ES6:
управление отдельными элементами:
> let set = new Set(); > set.add('red') > set.has('red') true > set.delete('red') true > set.has('red') falseопределение размера набора и его очистка:
> let set = new Set(); > set.add('red') > set.add('green') > set.size 2 > set.clear(); > set.size 0Я бы проверил изучение ES6 если вы хотите узнать больше о наборах в JavaScript. Книга бесплатно читать онлайн, но если вы хотите поддержать автора Д-Р Аксель Rauschmayer вы можете приобрести книгу около 30$.
Если вы хотите использовать наборы и ES6 теперь вы можете использовать Бабель, транспилер ES6-ES5 и его полифиллы.
Edit: по состоянию на 6 июня 2017 года большинство основных браузеров имеют полную поддержку набора в своих последних версиях (кроме IE 11). Это означает, что вам может не понадобиться babel, если вы не хотите поддерживать старые браузеры. Если вы хотите видеть совместимость в разных браузерах, включая ваш текущий браузер, проверьте таблица совместимости ES6 Kangax.
Я использую объекты dict в качестве наборов. Это работает со строками и числами, но я полагаю, что это вызовет проблемы, если вы хотите иметь набор объектов, использующих пользовательские операторы равенства и сравнения:
создание набора:
var example_set = { 'a':true, 'b':true, 'c':true }тестирование для включения в набор
if( example_set['a'] ){ alert('"a" is in set'); }добавление элемента в набор
example_set['d'] = true;удаление элемента из a набор
delete example_set['a'];
наборы не позволяют дублировать записи и обычно не гарантируют предопределенного заказа. Массивы делают оба из них, тем самым нарушая то, что означает быть набором (если вы не выполняете дополнительные проверки).
первый способ-это идиоматический JavaScript.
каждый раз, когда вы хотите сохранить пару ключ/значение, вы должны использовать объект JavaScript. Что касается массивов, есть несколько проблем:
индекс-это числовое значение.
нет простого способа проверить, находится ли значение в массиве без цикла.
набор не допускает дубликатов. Массив делает.
Если вы хотите создать набор из массива, просто:
let arr = [1, 1, 2, 1, 3]; let mySet = new Set(arr); // Set { 1, 2, 3 }это синтаксис сахара, который мне очень понравился при программировании на Python, поэтому я рад, что ES6 наконец-то позволил сделать то же самое.
Примечание: тут я понимаю что я сказал не прямо ответить на ваш вопрос. Причина, по которой у вас есть этот "хак" в ES5, заключается в том, что время поиска в объекте по ключам значительно быстрее (O(1)), чем в массиве (O(n)). В критически важных для производительности приложениях вы может пожертвовать этим битом читаемости или интуиции для лучшей производительности.
но эй, добро пожаловать в 2017, где вы можете использовать правильный Set во всех основных современных браузерах сейчас!
есть две проблемы с использованием голых объектов javascript для эмуляции наборов: во-первых, объект может иметь наследуемое свойство, которое будет завинчивать оператор "in", а во-вторых, вы можете хранить только скалярные значения таким образом, что создание набора объектов невозможно. Таким образом, реалистичность реализации комплектов должны быть предусмотрены способы
addиcontainsвместоinи присвоения имущества.
вы можете попробовать ведра, это библиотека структуры данных javascript и имеет все необходимое для управления наборами.