简体   繁体   English

Javascript map 带复合键

[英]Javascript map with composite keys

In JavaScript I want to store values to compound keys, similar to a C# dictionary with a tuple as key.在 JavaScript 中,我想将值存储到复合键,类似于以元组作为键的 C# 字典。 This is where I came across the Map class.这就是我遇到 Map class 的地方。 However, it does not seem to work quite as well as I would like it to.但是,它似乎并不像我希望的那样工作。 Here's my current approach:这是我目前的方法:

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'

I guess, that this has something to do that both objects with {a: 1, b: 1} have a different memory address and therefore are the same, but not identical.我想,这与具有{a: 1, b: 1}的两个对象具有不同的 memory 地址有关,因此是相同的,但不相同。 The Dictionary class in c# uses a hash function in background. c# 中的Dictionary class 在后台使用 hash ZC1C425268E68385D1ABZ5074C17A94F4。 Is there something similar in JS? JS中有类似的东西吗? Or a much easier approach?还是更简单的方法?

My real key object consistst of three strings.我的真正键 object 由三个字符串组成。

{} this operator will create a new object every time; {}这个算子每次都会创建一个新的 object; and a new object will have a different object refenece each time;并且新的 object 每次都会有不同的 object 参考; if you save the object reference and use that for multiple operation its ok;如果您保存 object 参考并将其用于多项操作,则可以; but since you are trying to use a new object refence every time it won't work;但是由于您每次都尝试使用新的 object 参考,因此它不起作用; you may either use a primitive type as key, or same object reference like the snippet below您可以使用原始类型作为键,也可以使用相同的 object 参考,如下面的片段

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

Your analysis is correct.你的分析是正确的。 It works like this because in Javascript you usually operate primitive objects that don't have all this hashing behavior attached to them out of the box.它是这样工作的,因为在 Javascript 中,您通常操作的原始对象没有开箱即用地附加所有这些散列行为。 Nothing stops you from implementing your own Dictionary with hash function in background though没有什么能阻止您在后台使用 hash function 实现自己的字典

 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

As to what to use, Map or object, the difference between Map and object is simply that object only supports string keys (also Symbols but irrelevant right now) while Map supports any value at a cost of using more resources, less compatibility with old browsers, and it's generally less handy to use than object (and also stops GC from cleaning out those objects you use as keys). As to what to use, Map or object, the difference between Map and object is simply that object only supports string keys (also Symbols but irrelevant right now) while Map supports any value at a cost of using more resources, less compatibility with old browsers ,并且它通常不如 object 方便使用(并且还会阻止 GC 清除您用作键的那些对象)。 That said, object is your choice here也就是说,object 是您的选择

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM