带有复合键的Javascript映射

时间:2020-04-15 14:32:16

标签: javascript dictionary

在JavaScript中,我想将值存储到复合键,类似于以元组作为键的C#字典。这是我遇到Map类的地方。但是,它似乎不如我希望的那样工作。这是我目前的方法:

var test = new Map();

test.set({a: 1, b: 1}, 'Bla');
test.set({a: 5, b: 7}, 'Blub');

test.get({a: 1, b: 1}); // ==> Returns undefined; would expect 'Bla'

我猜想,这与{a: 1, b: 1}的两个对象都具有不同的内存地址有关,因此是相同的,但并不相同。 c#中的Dictionary类在后台使用哈希函数。 JS中有类似的东西吗?还是更简单的方法?

我的真实键对象由三个字符串组成。

2 个答案:

答案 0 :(得分:2)

{},此操作符每次都会创建一个新对象;一个新对象每次都会具有不同的对象引用;如果保存对象引用并将其用于多项操作,则可以;但是由于您尝试每次都无法使用新的对象引用,因此,您可以使用原始类型作为键,也可以使用相同的对象引用(如下面的代码段

//approach 1 using same object reference
var test = new Map();
var obj = {a: 1, b: 1};
test.set(obj, 'Bla');
test.set({a: 5, b: 7}, 'Blub');
let result = test.get(obj); 
console.log(result);

// aproach 2 using JSON.stringify
test = new Map();
test.set(JSON.stringify({a: 1, b: 1}), 'Bla');
test.set({a: 5, b: 7}, 'Blub');
result = test.get(JSON.stringify({a: 1, b: 1})); 
console.log(result)

答案 1 :(得分:1)

您的分析是正确的。它之所以这样工作,是因为在Javascript中,您通常操作原始对象,而这些原始对象并没有开箱即用地附加所有这些哈希行为。但是,没有什么可以阻止您在后台使用哈希函数实现自己的Dictionary

class Dictionary {
  map = {}

  constructor(hashFunction) {
    this.hashFunction = hashFunction
  }

  set(key, item) {
    this.map[this.hashFunction(key)] = item
  }

  get(key) {
    return this.map[this.hashFunction(key)]
  }

  delete(key) {
    delete this.map[this.hashFunction(key)]
  }
}

const dict = new Dictionary((keyObject) => JSON.stringify(keyObject))
dict.set({ a: 1, b: 2 }, 'hello')
console.log(dict.get({ a: 1, b: 2 })) // hello

关于Map或对象使用什么,Map和对象之间的区别仅在于对象仅支持字符串键(也包括Symbols,但现在不相关),而Map支持任何值,但以使用更多资源,更少兼容性为代价使用旧的浏览器,通常不如使用对象方便(并且还阻止GC清除用作键的那些对象)。也就是说,在这里您可以选择对象