Способы создания набора в 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';
}
Ответы
Ответ 1
Наборы теперь доступны в ES2015 (он же ES6, т.е. ECMAScript 6). ES6 является текущим стандартом для JavaScript с июня 2015 года.
ECMAScript 6 имеет структуру данных Set, которая работает для произвольных значения, быстр и обрабатывает NaN правильно. -Аксель Раушмайер, Изучая ES6
Первые два примера из книги Акселя Раушмайера book Изучение 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. Книга бесплатна для чтения в Интернете, но если вы хотите поддержать автора, доктор Аксель Раушмайер вы можете купить книгу примерно за 30 долларов.
Если вы хотите использовать наборы и ES6, то теперь вы можете использовать Babel, транспортер от ES6 до ES5 и его полифилы.
Изменение: По состоянию на 6 июня 2017 года большинство основных браузеров имеют полную поддержку Set в своих последних версиях (кроме IE 11). Это означает, что вам может не понадобиться babel, если вы не хотите поддерживать старые браузеры. Если вы хотите увидеть совместимость в разных браузерах, включая ваш текущий браузер, проверьте таблицу совместимости Kangax ES6.
EDIT:
Просто уточнение по инициализации. Наборы могут принимать любые синхронные итерации в своем конструкторе. Это означает, что они могут принимать не только массивы, но также строки и итераторы. Возьмем, к примеру, следующий массив и инициализацию строки набора:
const set1 = new Set(['a','a','b','b','c','c']);
console.log(...set1);
console.log(set1.size);
const set2 = new Set("aabbcc");
console.log(...set2);
console.log(set2.size);
Ответ 2
Я использую объекты dict в качестве наборов. Это работает со строками и числами, но я предполагаю, что это вызовет проблемы, если вы хотите иметь набор объектов с использованием пользовательских операторов равенства и сравнения:
Создание набора:
var example_set =
{
'a':true,
'b':true,
'c':true
}
Тестирование для включения в набор
if( example_set['a'] ){
alert('"a" is in set');
}
Добавление элемента в набор
example_set['d'] = true;
Удаление элемента из набора
delete example_set['a']
;
Ответ 3
Наборы не позволяют дублировать записи и обычно не гарантируют предопределенное упорядочение. Массивы выполняют оба эти действия, тем самым нарушая то, что означает быть набором (если вы не выполняете дополнительные проверки).
Ответ 4
Первый способ - идиоматический JavaScript.
В любое время, когда вы хотите сохранить пару ключ/значение, вы должны использовать объект JavaScript. Что касается массивов, то есть несколько проблем:
-
Индекс - это числовое значение.
-
Нет простого способа проверить, не находится ли значение в массиве без прокрутки.
-
Набор не позволяет дублировать. Массив делает.
Ответ 5
Если вы хотите создать набор из массива, просто выполните:
let arr = [1, 1, 2, 1, 3];
let mySet = new Set(arr); // Set { 1, 2, 3 }
Этот синтаксис мне очень понравился при программировании на Python, поэтому я рад, что ES6 наконец-то позволил сделать то же самое.
ПРИМЕЧАНИЕ: тогда я понимаю, что то, что я сказал, прямо не ответило на ваш вопрос. Причина того, что у вас есть такой "взлом" в ES5, заключается в том, что время поиска в объекте по ключам значительно быстрее (O (1)), чем в массиве (O (n)). В приложениях, критичных к производительности, вы можете пожертвовать этим количеством читабельности или интуиции для повышения производительности.
Но добро пожаловать в 2017 год, где вы можете использовать правильный набор во всех основных современных браузерах!
Ответ 6
Устанавливается в ES6
/ES2015
:
ES6
/ES2015
теперь имеет встроенные наборы. Набор - это структура данных, которая позволяет хранить уникальные значения любого типа, будь то примитивные значения или ссылки на объекты. Набор может быть объявлен с использованием встроенного конструктора ES6
следующим образом:
const set = new Set([1, 2, 3, 4, 5]);
При создании набора с помощью конструктора Set наш вновь созданный объект set наследуется от Set.prototype
. Это имеет все виды вспомогательных методов и свойств. Это позволяет вам легко выполнять следующие действия:
Пример:
const set = new Set([1, 2, 3, 4, 5]);
// checkout the size of the set
console.log('size is: ' + set.size);
// has method returns a boolean, true if the item is in the set
console.log(set.has(1));
// add a number
set.add(6);
// delete a number
set.delete(1);
// iterate over each element using a callback
set.forEach((el) => {
console.log(el);
});
// remove all the entries from the set
set.clear();
Ответ 7
Есть две проблемы с использованием голых объектов javascript для эмулирования множеств: во-первых, объект может иметь унаследованное свойство, которое будет вставлять оператор "in", а во-вторых, вы можете хранить только скалярные значения таким образом, создавая набор объектов невозможно. Поэтому реалистичная реализация Sets должна предоставлять методы add
и contains
вместо простых in
и присвоений свойств.
Ответ 8
Вы можете попробовать Buckets, это библиотека структуры данных javascript и имеет все необходимое для управления наборами.