In JavaScript, all Objects act a bit like hashmaps. However, the keys to these hashmaps must be strings. If they're not, they're converted with toString()
. That means:
var a = {foo: 1};
var b = {bar: 2};
var o = {};
o[a] = 100;
o[b]; // 100
JSON.stringify(o); // '{"[object Object]":100}'
That is, since the toString()
of any plain Object is [object Object]
, they all address the same value.
I'd like to create a hashmap where Objects with the same properties and values address the same value, but objects with different properties or values address different values. That is:
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
My first instinct was to use JSON.stringify()
to turn objects into strings, but:
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}'
That is, JSON serialization is order-dependent.
Is there a good library or technique to implement a hashmap like this?
Update:
Equivalently, is there a good hashing function such that:
hash({foo: 1, bar: 2}) == hash({bar: 2, foo: 1})