Способы создания набора в 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 и имеет все необходимое для управления наборами.