Boo*_*oog 139 javascript hash set hashcode
基本上,我正在尝试创建一个独特对象的对象,一组.我有一个很好的想法,就是只使用带有对象的JavaScript对象作为属性名称.如,
set[obj] = true;
Run Code Online (Sandbox Code Playgroud)
这很有效.它适用于字符串和数字,但对于其他对象,它们似乎都"散列"到相同的值并访问相同的属性.是否有某种方法可以为对象生成唯一的哈希值?字符串和数字如何做,我可以覆盖相同的行为吗?
Kim*_*Kha 52
如果你想在JavaScript中使用类似Java的hashCode()函数,那就是你的:
String.prototype.hashCode = function(){
var hash = 0;
for (var i = 0; i < this.length; i++) {
var character = this.charCodeAt(i);
hash = ((hash<<5)-hash)+character;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
}
Run Code Online (Sandbox Code Playgroud)
这是Java(按位运算符)中的实现方式.
eye*_*ess 32
JavaScript对象只能使用字符串作为键(其他任何东西都转换为字符串).
或者,您可以维护一个数组,该数组索引相关对象,并使用其索引字符串作为对象的引用.像这样的东西:
var ObjectReference = [];
ObjectReference.push(obj);
set['ObjectReference.' + ObjectReference.indexOf(obj)] = true;
Run Code Online (Sandbox Code Playgroud)
显然它有点冗长,但是你可以编写一些处理它的方法,然后设置所有方法.
编辑:
您的猜测是事实 - 这是JavaScript中定义的行为 - 特别是发生toString转换意味着您可以在将用作属性名称的对象上定义您自己的toString函数. - olliej
这带来了另一个有趣的观点; 您可以在要散列的对象上定义toString方法,并且可以形成其哈希标识符.
Dan*_*ore 31
最简单的方法是为每个对象提供自己独特的toString方法:
(function() {
var id = 0;
/*global MyObject */
MyObject = function() {
this.objectId = '<#MyObject:' + (id++) + '>';
this.toString= function() {
return this.objectId;
};
};
})();
Run Code Online (Sandbox Code Playgroud)
我有同样的问题,这解决它完美的我以最小的大惊小怪,并且是一个更容易的是重新实现一些脂肪的Java风格Hashtable并加入equals()和hashCode()你的对象类.只要确保你没有将一个字符串'<#MyObject:12>粘贴到你的哈希中,否则它将清除你带有该id的退出对象的条目.
现在我所有的哈希都非常寒冷.我几天前刚刚发布了一篇关于这个话题的博客文章.
the*_*cko 18
我选择的解决方案类似于Daniel的解决方案,但不是使用对象工厂并覆盖toString,而是在首次通过getHashCode函数请求时向表中显式添加哈希.有点凌乱,但更符合我的需求:)
Function.prototype.getHashCode = (function(id) {
return function() {
if (!this.hashCode) {
this.hashCode = '<hash|#' + (id++) + '>';
}
return this.hashCode;
}
}(0));
Run Code Online (Sandbox Code Playgroud)
小智 18
您所描述的内容由Harmony WeakMaps涵盖,它是ECMAScript 6规范(下一版JavaScript)的一部分.即:一个集合,其中键可以是任何东西(包括未定义的)并且是不可枚举的.
这意味着除非您直接引用链接到它的键(任何对象!),否则无法获取对值的引用.这对于一系列与效率和垃圾收集相关的引擎实现原因很重要,但它也非常酷,因为它允许新的语义,如可撤销访问权限和传递数据而不暴露数据发送者.
来自MDN:
var wm1 = new WeakMap(),
wm2 = new WeakMap();
var o1 = {},
o2 = function(){},
o3 = window;
wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // A value can be anything, including an object or a function.
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // Keys and values can be any objects. Even WeakMaps!
wm1.get(o2); // "azerty"
wm2.get(o2); // Undefined, because there is no value for o2 on wm2.
wm2.get(o3); // Undefined, because that is the set value.
wm1.has(o2); // True
wm2.has(o2); // False
wm2.has(o3); // True (even if the value itself is 'undefined').
wm1.has(o1); // True
wm1.delete(o1);
wm1.has(o1); // False
Run Code Online (Sandbox Code Playgroud)
目前的Firefox,Chrome和Edge都提供WeakMaps.它们也在Node v7中支持,在v6中也支持--harmony-weak-mapsflag.
ijm*_*acd 13
对于我的具体情况,我只关心对象和原始值的对象是否相等.对我有用的解决方案是将对象转换为其JSON表示并将其用作哈希.有一些限制,例如密钥定义的顺序可能不一致; 但就像我说它对我有用,因为这些对象都是在一个地方生成的.
var hashtable = {};
var myObject = {a:0,b:1,c:2};
var hash = JSON.stringify(myObject);
// '{"a":0,"b":1,"c":2}'
hashtable[hash] = myObject;
// {
// '{"a":0,"b":1,"c":2}': myObject
// }
Run Code Online (Sandbox Code Playgroud)
JavaScript规范将索引属性访问定义为对索引名称执行toString转换.例如,
myObject[myProperty] = ...;
Run Code Online (Sandbox Code Playgroud)
是相同的
myObject[myProperty.toString()] = ...;
Run Code Online (Sandbox Code Playgroud)
这在JavaScript中是必要的
myObject["someProperty"]
Run Code Online (Sandbox Code Playgroud)
是相同的
myObject.someProperty
Run Code Online (Sandbox Code Playgroud)
是的,这让我很伤心:-(
我刚才把一个小的JavaScript模块放在一起,为字符串,对象,数组等生成哈希码(我只是将它提交给GitHub :))
用法:
Hashcode.value("stackoverflow")
// -2559914341
Hashcode.value({ 'site' : "stackoverflow" })
// -3579752159
Run Code Online (Sandbox Code Playgroud)
在ECMAScript 6中,现在可以按照Set您的方式工作:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
它已经在最新的Chrome,FF和IE11中提供.
根据标题,我们可以生成强大的SHA哈希值,在浏览器上下文中,它可用于从对象、参数数组、字符串或其他任何内容生成唯一的哈希值。
async function H(m) {
const msgUint8 = new TextEncoder().encode(m)
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8)
const hashArray = Array.from(new Uint8Array(hashBuffer))
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('')
console.log(hashHex)
}
/* Examples ----------------------- */
H("An obscure ....")
H(JSON.stringify( {"hello" : "world"} ))
H(JSON.stringify( [54,51,54,47] ))Run Code Online (Sandbox Code Playgroud)
我浏览器中的上述输出,对你来说也应该是一样的:
bf1cf3fe6975fe382ab392ec1dd42009380614be03d489f23601c11413cfca2b
93a23971a914e5eacbf0a8d25154cda309c3c1c72fbb9914d47c60f3cb681588
d2f209e194045604a3b15bdfd7502898a0e848e4603c5a818bd01da69c00ad19
Run Code Online (Sandbox Code Playgroud)
支持的算法:
SHA-1 (but don't use this in cryptographic applications)
SHA-256
SHA-384
SHA-512
Run Code Online (Sandbox Code Playgroud)
但是,对于仅用于避免冲突的简单 FAST 校验和哈希函数,请参阅CRC32(内容冗余校验)
您可能也对这种通过网络加密 API生成 HMAC 代码的类似方法感兴趣。
| 归档时间: |
|
| 查看次数: |
167711 次 |
| 最近记录: |