Pee*_*eja 10 javascript hashmap
在JavaScript中,所有对象都有点像哈希映射.但是,这些哈希映射的关键字必须是字符串.如果他们不是,他们就会被改变toString().这意味着:
var a = {foo: 1};
var b = {bar: 2};
var o = {};
o[a] = 100;
o[b]; // 100
JSON.stringify(o); // '{"[object Object]":100}'
Run Code Online (Sandbox Code Playgroud)
也就是说,由于toString()任何普通对象都是[object Object],它们都处理相同的值.
我想创建一个hashmap,其中具有相同属性和值的对象寻址相同的值,但具有不同属性或值的对象寻址不同的值.那是:
var a = {foo: 1};
var b = {bar: 2, baz: 3};
var c = {baz: 3, bar: 2};
var hash = new Hash();
hash.set(a, 100);
hash.get(b); // undefined
hash.set(b, 200);
hash.get(b); // 200
hash.get(c); // 200
Run Code Online (Sandbox Code Playgroud)
我的第一直觉是用来JSON.stringify()将对象变成字符串,但是:
var hash = {};
var b = {bar: 2, baz: 3};
var c = {baz: 3, bar: 2};
hash[JSON.stringify(b)] = 100
hash[JSON.stringify(b)] // 100
hash[JSON.stringify(c)] // undefined
JSON.stringify(b) // '{"bar":2,"baz":3}'
JSON.stringify(c) // '{"baz":3,"bar":2}'
Run Code Online (Sandbox Code Playgroud)
也就是说,JSON序列化依赖于顺序.
是否有一个很好的库或技术来实现这样的hashmap?
更新:
同样,是否有良好的散列函数,以便:
hash({foo: 1, bar: 2}) == hash({bar: 2, foo: 1})
Run Code Online (Sandbox Code Playgroud)
这是一个快速的概念验证......
我几乎没有测试过它,而且我确信会有它无法处理的极端情况。
性能将极其低效,因为该__createHash函数需要递归遍历任何对象的成员,然后对它们进行排序,以便生成满足您要求的“哈希”。
HashMap = function() {
this.get = function(key) {
var hash = this.__createHash(key);
return this.__map[hash];
};
this.set = function(key, value) {
var hash = this.__createHash(key);
this.__map[hash] = value;
};
this.__createHash = function(key) {
switch (typeof key) {
case 'function':
return 'function';
case 'undefined':
return 'undefined';
case 'string':
return '"' + key.replace('"', '""') + '"';
case 'object':
if (!key) {
return 'null';
}
switch (Object.prototype.toString.apply(key)) {
case '[object Array]':
var elements = [];
for (var i = 0; i < key.length; i++) {
elements.push(this.__createHash(key[i]));
}
return '[' + elements.join(',') + ']';
case '[object Date]':
return '#' + key.getUTCFullYear().toString()
+ (key.getUTCMonth() + 1).toString()
+ key.getUTCDate().toString()
+ key.getUTCHours().toString()
+ key.getUTCMinutes().toString()
+ key.getUTCSeconds().toString() + '#';
default:
var members = [];
for (var m in key) {
members.push(m + '=' + this.__createHash(key[m]));
}
members.sort();
return '{' + members.join(',') + '}';
}
default:
return key.toString();
}
};
this.__map = {};
}
Run Code Online (Sandbox Code Playgroud)