admin管理员组文章数量:1242807
In JavaScript I want to store values to pound keys, similar to a C# dictionary with a tuple as key. This is where I came across the 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. The Dictionary
class in c# uses a hash function in background. Is there something similar in JS? Or a much easier approach?
My real key object consistst of three strings.
In JavaScript I want to store values to pound keys, similar to a C# dictionary with a tuple as key. This is where I came across the 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. The Dictionary
class in c# uses a hash function in background. Is there something similar in JS? Or a much easier approach?
My real key object consistst of three strings.
Share Improve this question edited Apr 15, 2020 at 14:36 André Reichelt asked Apr 15, 2020 at 14:32 André ReicheltAndré Reichelt 1,6311 gold badge22 silver badges59 bronze badges 5-
Your analysis is right:
Map
uses reference equality on the keys and not value equality. If your objects just have three fixed strings, can you synthesize a key for map by bining them? E.g.makeKey = (({s1, s2, s3}) => `${s1}~${s2}~${s3}`
? Thentest.set(makeKey({a: 1, b: 1}), 'Bla')
...test.get(makeKey({a: 1, b: 1})
– Scott Sauyet Commented Apr 15, 2020 at 14:35 -
Sure, that would work. Would you rather use the
Map
class or a simple object in that case? – André Reichelt Commented Apr 15, 2020 at 14:37 -
2
Either one would be fine. To my mind, this restriction on
Map
makes it much less useful than it could be. – Scott Sauyet Commented Apr 15, 2020 at 14:38 - @ScottSauyet If you want, you can post your idea as an answer. – André Reichelt Commented Apr 15, 2020 at 14:53
-
1
Nah, simple enough to be just a ment. Besides, the
JSON.stringify
ment from Captain Mhmdrz_A is most likely a better idea. – Scott Sauyet Commented Apr 15, 2020 at 15:29
2 Answers
Reset to default 6Your 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. Nothing stops you from implementing your own Dictionary with hash function in background though
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 patibility 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). That said, object is your choice here
{}
this operator will create a new object every time; and a new object will have a different object refenece each time; if you save the object reference and use that for multiple operation its ok; but since you are trying to use a new object refence every time it won't work; you may either use a primitive type as key, or same object reference like the snippet below
//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)
本文标签: dictionaryJavascript map with composite keysStack Overflow
版权声明:本文标题:dictionary - Javascript map with composite keys - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1740129954a2229559.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论