Существует ли у JavaScript реализация установленной структуры данных?




js document methods (5)

Используйте стандартную структуру данных ECMAScript 2015 (ES6), которая очень проста в использовании:

var mySet = new Set();

mySet.add(1);
mySet.add(5);
mySet.add("some text");
var o = {a: 1, b: 2};
mySet.add(o);

mySet.has(1); // true
mySet.has(3); // false, 3 has not been added to the set
mySet.has(5);              // true
mySet.has(Math.sqrt(25));  // true
mySet.has("Some Text".toLowerCase()); // true
mySet.has(o); // true

mySet.size; // 4

mySet.delete(5); // removes 5 from the set
mySet.has(5);    // false, 5 has been removed

mySet.size; // 3, we just removed one value

Обновление для тех, кто использует AngularJs

Имейте в виду, что наборы не работают с ng-repeat . Так что лучше использовать массив и просто применить уникальный фильтр

Я ищу достойную реализацию установленной структуры данных в JavaScript. Он должен иметь возможность поддерживать элементы, которые являются обычными объектами JavaScript.

Пока что я нахожу только структуры struct Closure Library.Set , но мне не нравится тот факт, что он меняет мои данные.


Answer #1

В ES6 версии Javascript вы создали встроенный тип для set ( проверьте совместимость с вашим браузером ).

var numbers = new Set([1, 2, 4]); // Set {1, 2, 4}

Чтобы добавить элемент в набор, вы просто используете .add() , который работает в O(1) и либо добавляет элемент для установки (если он не существует), либо ничего не делает, если он уже существует. Вы можете добавить туда элемент любого типа (массивы, строки, числа)

numbers.add(4); // Set {1, 2, 4}
numbers.add(6); // Set {1, 2, 4, 6}

Чтобы проверить количество элементов в наборе, вы можете просто использовать .size . Также работает в O(1)

numbers.size; // 4

Чтобы удалить элемент из набора, используйте .delete() . Он возвращает true, если значение было (и было удалено), а false, если значение не было. Также работает в O(1) .

numbers.delete(2); // true
numbers.delete(2); // false

Чтобы проверить, существует ли элемент в наборе, используйте .has() , который возвращает true, если элемент находится в наборе, а false - в противном случае. Также работает в O(1) .

numbers.has(3); // false
numbers.has(1); // true

В дополнение к методам, которые вы хотели, есть несколько дополнительных:

  • numbers.clear(); просто удалит все элементы из набора
  • numbers.forEach(callback); итерация через значения набора в порядке вставки
  • numbers.entries(); создать итератор всех значений
  • numbers.keys(); возвращает ключи набора, которые являются такими же, как numbers.values()

Существует также Weakset, который позволяет добавлять только значения типа объекта.


Answer #2

Вы можете создать простую оболочку вокруг ключей хэш-таблицы, предоставленной моей jshashtable . У меня есть кто-то, кто-то стучит куда-то, что я буду выкапывать позже.

ОБНОВИТЬ

Я завершил и протестировал реализацию HashSet и загрузил ее в проект jshashtable в Google Code. Вы можете скачать его или просмотреть источник .

var s = new HashSet();
var o1 = {name: "One"}, o2 = {name: "Two"};
s.add(o1);
s.add(o2);
s.values(); // Array containing o1 and o2

Answer #3

Мне нравится Simple-JS-Set (возможно, потому, что я его написал). Он поддерживает любой объект JavaScript. Он имеет следующий API:

  • Set(hashFunction) : (Constructor) Создает новый набор с заданной hashFunction (по умолчанию JSON.stringify )
  • add(item) : добавьте элемент в набор
  • remove(item) : удалить элемент из набора
  • contains(item) : Возвращает, contains(item) ли элемент в наборе
  • size() : возвращает количество уникальных элементов в наборе
  • each(function(item), thisObj) : Выполнить функцию с каждым элементом в наборе в контексте thisObj

Answer #4

Я не думаю, что есть способ работать с хэш-кодом объекта, кроме сохранения его в самом объекте. Строго говоря, можно создать заданный класс без хеширования, используя простой линейный поиск, но это вряд ли будет эффективным.







set