Mise en œuvre JavaScript d'une structure de données définie

Je recherche une implémentation correcte d'une structure de données définie 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 les structures de la Bibliothèque de clôture . Oui , mais je n'aime pas le fait qu'il modifie mes données.

Des idées?

Vous pouvez construire une enveloppe simple autour des clés d'une table de hachage fournie par mon jshashtable . J'en ai frappé quelque part que je vais creuser plus tard.

METTRE À JOUR

J'ai complété et testé une implémentation de HashSet et l'ai téléchargé sur le projet jshashtable sur Google Code. 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 

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

Utilisez la structure de configuration standard 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

Soyez conscient que les ensembles ne fonctionnent pas avec ng-repeat . Il vaut donc mieux utiliser un tableau et appliquer un filtre unique

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

J'aime Simple-JS-Set (probablement parce que je l'ai écrit). Il prend en charge toute sorte d'objet JavaScript. Il a l'API suivante:

  • Set(hashFunction) : (Constructor) Instantez un nouvel ensemble avec la fonction hashFunction (par défaut, JSON.stringify )
  • add(item) : Ajouter un élément à l'ensemble
  • remove(item) : Supprimer un élément de l'ensemble
  • contains(item) : renvoie si l'élément est ou non contenu dans l'ensemble
  • size() : renvoie le nombre d'éléments uniques dans l'ensemble
  • each(function(item), thisObj) : exécuter une fonction avec chaque élément dans l'ensemble dans le contexte de thisObj

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

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

Pour ajouter un élément à l'ensemble, vous utilisez simplement .add() , qui s'exécute en O(1) et ajoute l'élément à définir (s'il n'existe pas) ou ne fait rien s'il est déjà là. Vous pouvez ajouter un élément de n'importe quel type (tableaux, chaînes, nombres)

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

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

 numbers.size; // 4 

Pour supprimer l'élément de l'ensemble, utilisez .delete() . Il renvoie true si la valeur était là (et a été supprimée) et false si la valeur n'existait pas. Fonctionne également en O(1) .

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

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

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

En plus des méthodes que vous vouliez, il y en a quelques-un supplémentaires:

  • numbers.clear(); Supprimerait tous les éléments de l'ensemble
  • numbers.forEach(callback); Itérant à travers 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.