JavaScript 中的字符串到整数对象散列

String to Integer Object hashing in JavaScript

SO 中有多个问题与我的问题类似,但 none 确实完全回答了它。

基本上,我想将对象作为 JavaScript 中的键。我知道 Map 是可能的,但是,它并不完全适用于我的用例。原因如下:

假设我有两个对象,var d1 = {a: 1, b: 2}var d2 = {a: 1, b: 2},以及一个地图 var m = new Map()。将 d1 添加到 m 时,当我调用 m.get(d2) 时,我将得到未定义。我认为这是因为 Map 以类似引用的方式工作。

但是,我想要以下功能:

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

我想到的一种做法是不使用Map,而是一个简单的JS对象。键将是 JSON.stringify(obj) 并且当我想从对象中获取值时,我使用 JSON.parse(key) 然后执行对象相等性检查(Object.getOwnPropertyNames 然后逐一检查)。

但是,我觉得这种方法比它应该的更复杂和耗时。我正在寻找的可能是某种哈希函数,它可以有效地将具有 String 类型键的对象映射到 Number 类型的值(在我的例子中是整数)。此外,顺序可以不同(d1 = {a: 1, b: 2} 应该等于d2 = {b: 2, a: 1})。

如何设计一个高效的hash函数来配合任一JSObjects/Maps完成上述操作?

编写一个函数,将对象转换为具有一致顺序键的字符串。

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)));