web-dev-qa-db-fra.com

JavaScript a-t-il une implémentation d'une structure de données d'ensemble?

Je recherche une implémentation décente d'une structure de données d'ensemble en JavaScript. Il devrait être capable de supporter des éléments qui sont des objets JavaScript simples.

Jusqu'à présent, je n'ai trouvé que la structure structs.Set de la bibliothèque de fermeture , mais je n'aime pas le fait qu'elle modifie mes données.

30
Tim Molendijk

Vous pouvez construire un simple wrapper autour des clés d'une table de hachage fournie par mon jshashtable . J'en ai un qui va frapper quelque part que je vais extraire plus tard.

UPDATE

J'ai terminé et testé une implémentation de HashSet et je l'ai téléchargée dans le projet jshashtable sur GitHub. Vous pouvez le télécharger ou voir la source .

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

ECMAScript 6 l'a

Spec: http://www.ecma-international.org/ecma-262/6.0/#sec-set-constructor

Utilisation: https://github.com/lukehoban/es6features#map--set--weakmap--weakset

Exemple:

var s = new Set()
s.add("hello").add("goodbye").add("hello")
s.size === 2
s.has("hello") === true

Un module qui l'implémente pour les navigateurs sans support: https://github.com/medikoo/es6-set

Je ne pense pas qu'il existe un moyen de travailler avec le code de hachage de l'objet autre que de le stocker dans l'objet même. Strictement parlant, il est possible de créer une classe d'ensemble sans hachage, en utilisant une recherche linéaire simple, mais cela ne serait guère efficace.

2
user187291

Utilisez la structure standard Set Data d'ECMAScript 2015 (ES6) vraiment facile à utiliser:

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

Mise à jour pour ceux qui utilisent AngularJs

Sachez que les ensembles ne fonctionnent pas avec ng-repeat. Il est donc préférable d’utiliser un tableau et d’appliquer un filtre unique.

2
CommonSenseCode

J'aime Simple-JS-Set (probablement parce que je l'ai écrit). Il supporte n'importe quelle sorte d'objet JavaScript. Il a l'API suivante:

  • Set(hashFunction): (constructeur) instancie un nouvel ensemble avec la variable hashFunction (définie par défaut sur JSON.stringify)
  • add(item): Ajouter un élément à l'ensemble
  • remove(item): Supprimer un élément de l'ensemble
  • contains(item): Indique si l'élément est contenu ou non dans l'ensemble
  • size(): Retourne le nombre d'éléments uniques dans l'ensemble
  • each(function(item), thisObj): Exécute une fonction avec chaque élément de l'ensemble dans le contexte de thisObj
1
Lukas

Dans la version ES6 de Javascript, vous avez intégré le type pour set ( vérifiez la compatibilité avec votre navigateur ).

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

To ajoute un élément à l'ensemble que vous utilisez simplement .add(), qui s'exécute dans O(1) et ajoute l'élément à définir (s'il n'existe pas) ou ne fait rien s'il est déjà présent. Vous pouvez y ajouter des éléments de tout type (tableaux, chaînes, nombres)

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

Pour vérifiez le nombre d'éléments dans l'ensemble, vous pouvez simplement utiliser .size. Fonctionne également dans O(1)

numbers.size; // 4

To supprime l'élément de l'ensemble use .delete(). Il renvoie true si la valeur était là (et a été supprimé) et false si la valeur n'existait pas. Fonctionne également dans O(1).

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

To vérifie si l'élément existe dans un ensemble, utilisez .has(), qui renvoie true si l'élément est dans l'ensemble et false sinon. Fonctionne également dans O(1).

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

En plus des méthodes que vous vouliez, il y en a peu d'autres:

  • numbers.clear(); enlèverait simplement tous les éléments de l'ensemble
  • numbers.forEach(callback); itérant les valeurs de l'ensemble dans l'ordre d'insertion
  • numbers.entries(); créer un itérateur de toutes les valeurs
  • numbers.keys(); renvoie les clés de l'ensemble qui est identique à numbers.values()

Il existe également un Weakset qui permet d’ajouter uniquement des valeurs de type objet.

0
Salvador Dali