Est-il une sorte de code de hachage fonction en JavaScript?
En gros, je suis en train de créer un objet unique d'objets, un ensemble. J'ai eu la brillante idée d'utiliser un objet JavaScript avec des objets pour les noms de propriété. Tels que,
set[obj] = true;
Cela fonctionne, jusqu'à un certain point. Il fonctionne très bien avec de la ficelle et des chiffres, mais avec d'autres objets, ils semblent tous "hash" à la même valeur et accéder à la même propriété. Est-il une sorte de façon, je peux générer une unique valeur de hachage pour un objet? Comment faire des chaînes et des nombres le faire, puis-je remplacer le même comportement?
- La raison pour laquelle les objets de tous les "hash" à la même valeur est parce que vous n'ont pas outrepassé leurs méthodes toString. Depuis les touches sont nécessaires pour être des chaînes de caractères, la méthode toString est automatiquement appelée pour obtenir une clé valide de sorte que tous vos objets de la conversion à la même chaîne par défaut: "[object object]".
JSON.stringify(obj)
ouobj.toSource()
peut travailler pour vous en fonction du problème et de la plate-forme cible.- JSON.stringify(obj) littéralement juste convertit le (tout) objet en chaîne de caractères. Donc, vous serait essentiellement une simple copie de l'objet sur lui-même. C'est inutile, un gaspillage de l'espace et de ne pas optimale.
- Vrai, c'est pourquoi ça dépend quel est ton problème. Quand j'ai trouvé cette question par le biais de google ma solution finale a été d'appeler toSource() sur les objets. Une autre méthode serait d'utiliser un classique de hachage sur la source.
toSource
ne fonctionnent pas dans Chrome btw
Vous devez vous connecter pour publier un commentaire.
JavaScript les objets ne peuvent utiliser les chaînes de caractères comme des clés (tout le reste est converti en chaîne de caractères).
Vous pouvez, sinon, de maintenir un tableau qui répertorie les objets en question, et l'utilisation de son indice de chaîne comme une référence à l'objet. Quelque chose comme ceci:
Évidemment, c'est un peu verbeux, mais vous pouvez les écrire sur un couple de méthodes que de la gérer et de get et set tous, bon gré mal gré.
Edit:
Cela nous amène à un autre point intéressant; vous pouvez définir une méthode toString sur les objets que vous voulez de hachage, et qui peuvent former leur identificateur de hachage.
Si vous voulez un hashCode() de la fonction comme Java en JavaScript, qui est la vôtre:
Qui est la voie de la mise en œuvre en Java (opérateur au niveau du bit).
pickOne["helloo".hashCode() % 20]
pour un tableaupickOne
avec 20 éléments. J'ai euundefined
parce que le code de hachage est négatif, c'est donc un exemple de quelqu'un qui (me) implicitement supposé positif des codes de hachage.La façon la plus simple de le faire est de donner à chacun de vos objets de sa propre
toString
méthode:J'ai eu le même problème et cela a résolu parfaitement pour moi, avec un minimum de tracas, et a été beaucoup plus facile que la re-mise en œuvre de certaines gras Java style
Hashtable
et l'ajout deequals()
ethashCode()
de vos classes d'objet. Assurez-vous juste que vous n'avez pas de coller une chaîne de caractères '<#Monobjet:12> dans votre hash ou il effacera l'entrée de votre sortie de l'objet avec l'id.Maintenant, toutes mes hachages sont totalement refroidir. J'ai également posté une entrée de blog il y a quelques jours à propos de exacte de ce sujet.
equals()
ethashCode()
de sorte que l'équivalent de deux objets ont la même valeur de hachage. À l'aide de la méthode ci-dessus signifie que chaque instance deMyObject
aura une chaîne unique, ce qui signifie que vous devrez garder une référence à cet objet à jamais récupérer la valeur correcte de la carte. La clé est vide de sens, parce qu'il n'a rien à voir avec la singularité d'un objet. UtiletoString()
fonction devra être mise en œuvre pour le type d'objet à l'aide d'une clé.toString
pour les objets tels que directement les cartes à une relation d'équivalence, de sorte que les deux objets de créer la même chaîne ssi ils sont considérés comme des "égaux".toString()
pour vous permettre d'utiliser unObject
comme unSet
. Je pense que j'ai mal compris votre réponse en essayant de fournir une solution générique pour éviter d'écrire untoString()
équivalent deequals()
ouhashCode()
sur une base de cas par cas.La solution que j'ai choisi est similaire à celle de Daniel, mais plutôt que d'utiliser un objet de l'usine et de remplacer les toString, j'ai ajouter explicitement la valeur de hachage de l'objet lorsqu'il est demandé pour la première fois par le biais d'un getHashCode fonction. Un peu bordélique, mais c'est mieux pour mes besoins 🙂
Object.defineProperty
avecenumerable
ensemble defalse
, afin de ne pas bloquer toutefor .. in
boucles.Ce que vous avez décrit est couvert par l'Harmonie WeakMaps, une partie de la ECMAScript 6 spécification (prochaine version de JavaScript). C'est: un jeu où les touches peuvent être n'importe quoi (y compris indéfini) et est non-énumérable.
Cela signifie qu'il est impossible d'obtenir une référence à une valeur, sauf si vous avez une référence directe à la touche (n'importe quel objet!) que des liens vers elle. Il est important pour un tas de moteur de la mise en œuvre des raisons liées à l'efficacité et à la collecte des ordures, mais c'est aussi super cool dans la mesure où elle permet de sémantique comme être révoquées autorisations d'accès et de transmission des données sans exposer les données de l'expéditeur.
De MDN:
WeakMaps sont disponibles dans le courant Firefox, Chrome et Edge. Ils sont également pris en charge dans le Nœud v7 , et en v6 avec le
--harmony-weak-maps
drapeau.Map
?var m = new Map();m.set({},"abc"); console.log(m.get({}) //=>undefined
Il ne fonctionne que si vous avez la même variable d'origine que vous avez référencé dans la commande set. E. G.var m = new Map();a={};m.set(a,"abc"); console.log(m.get(a) //=>undefined
Pour mon cas, je ne se soucient que de l'égalité de l'objet autant que les clés et les valeurs primitives aller. La solution qui a fonctionné pour moi a été la conversion de l'objet à sa représentation JSON et en utilisant ce que le hachage. Il y a des limites telles que l'ordre de définition de clé potentiellement incompatibles, mais, comme je l'ai dit, il a travaillé pour moi parce que ces objets ont tous été générés en un seul endroit.
Le JavaScript spécification définit indexé l'accès à la propriété en réalisant une toString de conversion sur le nom de l'index. Par exemple,
est le même que
Cela est nécessaire, car en JavaScript
est le même que
Et oui, ça me rend triste aussi bien 🙁
J'ai mis en place un petit JavaScript module il y a un moment pour produire hashcodes pour les cordes, les objets, les tableaux, etc. (J'ai juste commis à GitHub 🙂 )
Utilisation:
var hash1 = Hashcode.value({ a: 1, b: 2 }); var hash2 = Hashcode.value({ a: 2, b: 1 }); console.log(hash1, hash2);
journal2867874173
2867874173
Dans ECMAScript 6, il y a maintenant un
Set
qui fonctionne à la manière dont vous le souhaitez: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SetIl est déjà disponible dans le dernier Chrome, FF, et IE11.
Référence: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
vous pouvez utiliser Es6 symbole pour créer la clé unique et l'accès de l'objet.
Chaque symbole valeur renvoyée par le Symbole() est unique. Une valeur de symbole peut être utilisé comme identifiant pour les propriétés de l'objet; c'est le type de données du seul but.
Voici ma solution simple qui retourne un entier unique.
Ma solution introduit une fonction statique pour le mondial
Object
objet.Je pense que c'est plus pratique avec d'autres objets de manipuler des fonctions en JavaScript.
Si vous voulez vraiment régler le problème (je vais en Java), alors vous serez aux abois pour trouver une solution en JavaScript. La plupart des développeurs de recommander une clé unique pour représenter chaque objet, mais ce n'est pas définie, que vous pouvez obtenir deux objets identiques, chacune avec une clé unique. L'API Java fait le travail de vérification de doublons en comparant le code de hachage de valeurs, pas de touches, et depuis il n'y a pas de code de hachage de la valeur de la représentation des objets en JavaScript, il devient presque impossible de faire de même. Même le Prototype de bibliothèque JS admet cette lacune, quand il dit:
http://www.prototypejs.org/api/hash
En plus de eyelidlessness réponse, voici une fonction qui retourne un reproductible, ID unique pour n'importe quel objet:
Comme vous pouvez le voir il utilise une liste de look-up qui est très inefficace, cependant, c'est le meilleur que j'ai pu trouver pour l'instant.
Si vous souhaitez utiliser des objets comme des clés dont vous avez besoin pour remplacer leur Méthode toString, comme déjà mentionné ici. Les fonctions de hachage qui ont été utilisés sont tous beaux, mais ils ne fonctionnent que pour les mêmes objets qui ne sont pas pour l'égalité des objets.
J'ai écrit une petite bibliothèque qui crée à partir de hachages des objets, que vous pouvez facilement utiliser à cette fin. Les objets peuvent même avoir un ordre différent, les valeurs de hachage sera le même. En interne, vous pouvez utiliser différents types de pour votre de hachage (djb2, md5, sha1, sha256, sha512, ripemd160).
Voici un petit exemple tiré de la documentation:
Le package peut être utilisé soit dans le navigateur et dans le Node-Js.
Référentiel: https://bitbucket.org/tehrengruber/es-js-hash
Si vous voulez avoir des valeurs uniques dans une recherche d'objet que vous pouvez faire quelque chose comme ceci:
La création d'un objet de recherche
Configurer le hashcode de la fonction
Objet
Tableau
D'autres types
Résultat Final
{ 1337: true, 01132337: true, StackOverflow: true }
Ne remarque que
getHashCode
ne retourne pas de valeur lorsque l'objet ou le tableau est videCeci est similaire à @ijmacd solution que
getHashCode
n'est pas a laJSON
dépendance.Je vais essayer d'aller un peu plus loin que d'autres réponses.
Même si JS eu de meilleures hachage de soutien, il ne serait pas comme par magie de hachage tout à la perfection, dans de nombreux cas, vous devrez définir votre propre fonction de hachage. Par exemple Java a un bon malaxage de soutien, mais vous avez encore de penser et de travailler.
Un problème avec le terme de hachage/hashcode ... il y a de hachage cryptographique et non de hachage cryptographiques. L'autre problème, c'est que vous devez comprendre pourquoi le hachage est utile et comment il fonctionne.
Lorsque nous parlons de hachage en JavaScript ou Java, la plupart du temps, nous parlons de non-hachage cryptographique, généralement sur le hachage pour hashmap/hashtable (à moins que nous travaillons sur d'authentification ou de mots de passe, qui vous pourriez faire côté serveur à l'aide de NodeJS ...).
Cela dépend de ce que les données que vous avez et ce que vous voulez atteindre.
Vos données naturelles "simple" unicité:
Vos données naturelles "composite" unicité:
Vous n'avez aucune idée de ce que vos données seront:
Il n'y a pas de magie efficace de hachage technique pour les données inconnues, dans certains cas, il est assez facile, dans d'autres cas, vous pouvez avoir à réfléchir à deux fois. Donc, même si JavaScript/ECMAScript ajoute plus de soutien, il n'y a pas de magie de la langue de solution pour ce problème.
Dans la pratique, vous avez besoin de deux choses: assez d'unicité, assez de vitesse
En outre, il est bon d'avoir: "hashcode égal si les objets sont égaux"
J'ai combiné les réponses de eyelidlessness et KimKha.
Ce qui suit est un service angularjs et il prend en charge des nombres, des chaînes et des objets.
Exemple D'Utilisation:
Sortie
Explication
Comme vous pouvez le voir le cœur du service est la fonction de hachage créé par KimKha.J'ai ajouté les types de chaînes, de sorte que le sturucture de l'objet aurait également une incidence sur la dernière valeur de hachage.Les touches sont cryptées pour éviter de tableau|objet de collisions.
eyelidlessness objet de comparaison est utilisé pour prévenir infinit de la récursivité par l'auto-référencement des objets.
Utilisation
J'ai créé ce service pour que je puisse avoir une erreur de service qui est accessible avec les objets. Pour qu'un service peut s'inscrire une erreur avec un objet donné et un autre peut déterminer si des erreurs ont été trouvées.
ie
JsonValidation.js
UserOfData.js
Ce serait de retour:
Tout
Ce serait de retour