В Eloquent JavaScript, Глава 4, набор значений создается путем создания объекта и сохранения значений как имен свойств, присвоения произвольных значений (например, true) как значений свойств. Чтобы проверить, содержится ли уже значение в наборе, используется in
оператор:
var set = {};
if (!'Tom' in set) {
set.Tom = true;
}
Это идиоматический JavaScript? Не было бы лучше использовать массив?
var set = [];
if (!'Tom' in set) {
set.push = 'Tom';
}
javascript
set
вспомогательный метод
источник
источник
'Tom' in set
верно, будет выглядеть? Похоже, у вас есть неправильные предположения о чем-то , и я пытаюсь выяснить, о чем .if(!('Tom' in set))
. В настоящее время это означаетfalse in set
с!'Tom' === false
.Ответы:
Наборы теперь доступны в ES2015 (он же ES6, то есть ECMAScript 6). ES6 является текущим стандартом для JavaScript с июня 2015 года.
Первые два примера из книги Акселя Раушмайера Exploring 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 долларов.
Если вы хотите использовать Sets и ES6, теперь вы можете использовать Babel , транспилятор ES6 в ES5 и его полифилы.
Изменить: по состоянию на 6 июня 2017 года большинство основных браузеров имеют полную поддержку Set в своих последних версиях (кроме IE 11). Это означает, что вам может не понадобиться babel, если вы не хотите поддерживать старые браузеры. Если вы хотите увидеть совместимость в разных браузерах, включая ваш текущий браузер, проверьте таблицу совместимости Kangax с ES6 .
РЕДАКТИРОВАТЬ:
Просто пояснение по инициализации. Наборы могут принимать любые синхронные итерации в своем конструкторе. Это означает, что они могут принимать не только массивы, но также строки и итераторы. Возьмем, например, следующий массив и инициализацию набора строк:
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);
Оба выхода массива и строки одинаковы. Обратите внимание, что
...set1
это синтаксис распространения . Похоже, что каждый элемент итерации добавляется к набору один за другим, поэтому, поскольку и массив, и строка имеют одинаковые элементы и поскольку элементы находятся в одном порядке, набор создается одинаково. Еще одна вещь, которую следует отметить в отношении наборов, - это при повторении по ним порядок итерации следует за порядком, в котором элементы были вставлены в набор. Вот пример итерации по набору:const set1 = new Set(['a','a','b','b','c','c']); for(const element of set1) { console.log(element); }
Поскольку вы можете использовать любую итерацию для инициализации набора, вы даже можете использовать итератор из функции генератора . Вот два таких примера инициализации итератора, которые дают одинаковый результат:
// a simple generator example function* getLetters1 () { yield 'a'; yield 'a'; yield 'b'; yield 'b'; yield 'c'; yield 'c'; } // a somewhat more commonplace generator example // with the same output as getLetters1. function* getLetters2 (letters, repeatTimes) { for(const letter of letters) { for(let i = 0; i < repeatTimes; ++i) { yield letter; } } } console.log("------ getLetters1 ------"); console.log(...getLetters1()); const set3 = new Set(getLetters1()); console.log(...set3); console.log(set3.size); console.log("------ getLetters2 ------"); console.log(...getLetters2('abc', 2)); const set4 = new Set(getLetters2('abc', 2)); console.log(...set4); console.log(set4.size);
Функции генератора в этих примерах можно было бы просто написать так, чтобы не повторяться, но если функция генератора более сложная и пока следующее не влияет на производительность слишком отрицательно, вы можете использовать метод Set, чтобы получить только значения от генератора, который не Не повторяю.
Если вы хотите узнать больше о наборах, не читая главу его книги доктора Раушмайера, вы можете ознакомиться с документацией MDN на Set . В MDN также есть больше примеров итерации по набору, таких как использование
forEach
и использование.keys
,.values
и.entries
методы. В MDN также есть такие примеры, как объединение множеств, пересечение множеств, разность множеств, симметричная разность множеств и проверка расширенных множеств. Надеюсь, что большинство из этих операций станут доступны в JavaScript без необходимости создавать собственные поддерживающие их функции. Фактически, это предложение TC39 по новым методам Set, которые, мы надеемся, должны добавить следующие методы в Set в JavaScript в какой-то момент времени, если предложение достигнет стадии 4:источник
Я использую объекты 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']
;источник
Set
. Это помогло.Наборы не допускают дублирования записей и обычно не гарантируют предопределенный порядок. Массивы делают и то, и другое, тем самым нарушая то, что значит быть набором (если вы не выполняете дополнительные проверки).
источник
arr[id] = {"name": "Jake"};
Первый способ - идиоматический 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 во всех основных современных браузерах!
источник
Устанавливается в
ES6
/ES2015
:ES6
/ES2015
теперь имеет встроенные наборы. Набор - это структура данных, которая позволяет хранить уникальные значения любого типа, будь то примитивные значения или ссылки на объекты. Набор может быть объявлен с помощьюES6
встроенного конструктора набора следующим образом:const set = new Set([1, 2, 3, 4, 5]);
При создании набора с помощью конструктора 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();
Совместимость с браузером:
Все основные браузеры теперь полностью поддерживают наборы, за исключением IE, в котором отсутствуют некоторые функции. Для точной справки обратитесь к документации mdn .
источник
Есть две проблемы с использованием голых объектов javascript для имитации наборов: во-первых, объект может иметь унаследованное свойство, которое будет включать оператор "in", и, во-вторых, вы можете хранить только скалярные значения таким образом, а создание набора объектов не возможно. Следовательно, реалистичная реализация Sets должна предоставлять методы,
add
аcontains
не простые назначенияin
и свойства.источник
set={};set[{x:1}]=123;alert(set[{z:99}])
Вы можете попробовать Buckets , это библиотека структуры данных javascript, в которой есть все необходимое для управления наборами.
источник
Основы создания и использования объекта Set 🔷
let mySet = new Set() mySet.add(2) // Set {2} mySet.add(7) // Set {2, 7} mySet.add(7) // Set {2, 7} mySet.add('my text') // Set {2, 7, 'my text'} let myObj = { a: 1, b: 2 } mySet.add(myObj) // Set {2, 7, 'my text', {...}} mySet.has(2) // true mySet.has(myObj) // true mySet.size // 4
Итерация
for (let item of mySet) console.log(item) // 2, 7, 'my text', {a:1, b:2} mySet.forEach(value => console.log(value)) // 2, 7, 'my text', {a:1, b:2}
Преобразовать в массив
var myArr = Array.from(mySet) // [2, 7, 'my text', {a:1, b:2}]
источник