I wrote this message in StackOverflow and just before clicking the Send button I stumbled upon the solution. I don’t want to lose it, and I don’t have time today to publish the solution, so I decided to do it in two parts. First, publish the question and later (tomorrow?) publish the solution. Here we go!
I can set() a value using an array as a key in a JS Map, but it seems that there isn’t a clean interface to access that same value using the symmetric get() method:
let z = new Map {} z.set([1,2], "a"); // Works as expected: Map { [ 1, 2 ] => 'a' } z.get([1,2]); // undefined (!) |
I suspect that this behaviour has something to do with the fact that in JS:
[1,2] == [1,2] false |
I can use [1,2].toString() as a key and then the z.get([1,2].toString()) method works as expected, but I’m wondering if there is in any other «cleaner» way to code that.
UPDATE:
Well, Map objects are a new addition of ES6. And it seems that ES6 has a problem with Maps if you are trying to use them with object keys. This has been discussed here
https://esdiscuss.org/topic/maps-with-object-keys and here https://stackoverflow.com/questions/21838436/map-using-tuples-or-objects .
A solution that WorksForMe was proposed in that same StackOverflow thread, using an ad-hoc built HashMap class, that takes a hash function as parameter to properly store and use object keys (specifically, for my problem, array keys)
function HashMap(hash) { var map = new Map; var _set = map.set; var _get = map.get; var _has = map.has; var _delete = map.delete; map.set = function (k,v) { return _set.call(map, hash(k), v); } map.get = function (k) { return _get.call(map, hash(k)); } map.has = function (k) { return _has.call(map, hash(k)); } map.delete = function (k) { return _delete.call(map, hash(k)); } return map; } |
I have used it as follows (note that JSON.stringify is NOT a hash function, but as I said, it works for my example because I certainly know that my array values are not going to have duplicates). I should think about a proper hash function or use something from here, but as I said, I’m lazy today 🙂
let z = new HashMap(JSON.stringify); z.set([1,2], "a"); z.get([1,2]); // "a" |