Search code examples
javascriptdictionaryhash-function

String to Integer Object hashing in JavaScript


There are multiple questions here in SO that are similar to my question, but none really answers it completely.

Basically, I want to have objects as keys in JavaScript. I know it is possible with Map, however, it doesn't fully apply to my use-case. Here is the reason:

Let's say I have two objects, var d1 = {a: 1, b: 2} and var d2 = {a: 1, b: 2}, and a Map var m = new Map(). When adding d1 to m, when I call m.get(d2) I will get undefined. I assume it is because Map works in a reference-like manner.

However, I want the following functionality:

m.set(d1, 'hit');
m.get(d2) // should return 'hit' because properties and values of d1 = d2

One approach I thought of was not to use Map, but a simple JS object. Keys would be JSON.stringify(obj) and when I want to get a value from the object, I use JSON.parse(key) and then perform object equality check (Object.getOwnPropertyNames and then checking one-by-one).

However, I feel that this approach is way more complex and time-consuming than it should be. What I am looking for is probably a hash function of some sort that would efficiently map a object with keys of type String to values of type Number (integer in my case). Also, the ordering can be different (d1 = {a: 1, b: 2} should equal d2 = {b: 2, a: 1}).

How to design an efficient hash function to work with either JS Objects/Maps to perform the above-mentioned operations?


Solution

  • Write a function that turns the object into a string with the keys in a consistent order.

    function objToKey(obj) {
      Object.keys(obj).sort().map(k => `${k}:${obj[k]}`).join(',');
    }
    
    var d1 = {a: 1, b: 2},
      d2 = {b: 2, a: 1},
      m = new Map();
    
    m.set(objToKey(d1), "foo");
    console.log(m.get(objToKey(d2)));