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.
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
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.
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
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.
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'ensembleremove(item)
: Supprimer un élément de l'ensemblecontains(item)
: Indique si l'élément est contenu ou non dans l'ensemblesize()
: Retourne le nombre d'éléments uniques dans l'ensembleeach(function(item), thisObj)
: Exécute une fonction avec chaque élément de l'ensemble dans le contexte de thisObj
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'ensemblenumbers.forEach(callback);
itérant les valeurs de l'ensemble dans l'ordre d'insertionnumbers.entries();
créer un itérateur de toutes les valeursnumbers.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.