Подтвердить что ты не робот

Способы создания набора в 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';
}
4b9b3361

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