1

I'm wondering if it is possible to add JSON as the key value for a map.set.

Adding the JSON as an object works fine:

var theMap = new Map();
var key = {field1 : 'value1', field2: 'value2'};
theMap.set(key, 'foo');

Adding the JSON during the set does not work:

var theMap = new Map();
theMap.set({field1 : 'value1', field2: 'value2'}, 'bar');

Anyone any ideas if something like this is possible?

n1234
  • 155
  • 1
  • 2
  • 9
  • 6
    You're not adding JSON, you're adding an object. – Herohtar Nov 15 '18 at 20:59
  • 5
    The second way also works, but is quite useless, as you did not keep a reference to that object. – trincot Nov 15 '18 at 21:00
  • 3
    Why does half of the programmers use the term JSON for something it is not? I don't get it. Is there some famous site out there that confuses them into this wrong use of the term? – trincot Nov 15 '18 at 21:01
  • Read [this answer](https://stackoverflow.com/a/383699/574531) to understand what JSON actually is. – Herohtar Nov 15 '18 at 21:08
  • I just tried it in Chrome Dev Console and it works both ways. Could you maybe clarify what your intent is? That way we could suggest a possible alternative easier. – HighHopes Nov 15 '18 at 21:26
  • Okay everyone, I apologise, it is not JSON - thanks for the education :-) – n1234 Nov 15 '18 at 21:28
  • @Casey Have you tried doing a map.get? I'm basically wanting to have multiple keys, but have the flexibility of not everything being required (which is why I thought JSON/object was a good fit). I'm trying to avoid concatenating a string together for the key e.g. `theMap.set('house-married-somethingelse', 'foo');` – n1234 Nov 15 '18 at 21:33
  • If I understand correctly, you're trying to set up something where a few different keys will return the same value. I can come up with a couple ways to do this, but could you maybe give me a scenario where this would be preferred/necessary so I can think through this better? – HighHopes Nov 16 '18 at 14:06

2 Answers2

2

First of all you are not using JSON your are using an object reference as a key. This is totally fine for a map data structure in javascript. A map can have anything for its key and value which is which is one of the reasons to sometimes pick this data structure instead of an object (which is quite similar, also key value pairs).

var theMap = new Map();
var key = {field1 : 'value1', field2: 'value2'};
theMap.set(key, 'foo');

In your second example:

var theMap = new Map();
theMap.set({field1 : 'value1', field2: 'value2'}, 'bar');

You are creating an object on the fly via an object literal. You are then using this created object literal as key for the value (the string 'bar' in this case).

Willem van der Veen
  • 33,665
  • 16
  • 190
  • 155
  • 2
    *"the object will be garbage collected"*: It would be garbage collected if it were a `WeakMap`, but in a `Map` it will not be garbage collected unless the `Map` itself is no longer referenced. – trincot Nov 15 '18 at 21:10
1

When you use an object as a key for a Map, accessing that key is done via object identity. In other words you need to look it up with the same object, not an object with the same values.

Consider:

var theMap = new Map();
let obj = {field1 : 'value1', field2: 'value2'}

theMap.set(obj, 'bar');

// you have a reference to obj
// so you can access the value with get
console.log(theMap.get(obj))

// but if you do this
theMap.set({field1 : 'value1', field2: 'value2'}, 'foo');

// you can't get foo with `obj` because having the same keys and values
// doesn't mean they are the same object:

console.log("objects are the same? ", obj === {field1 : 'value1', field2: 'value2'})

// Still setting the value in the map worked.
// You just have two distinct objects as keys 
 
console.log("keys:", ...theMap.keys())
Mark
  • 90,562
  • 7
  • 108
  • 148
  • Interesting, thanks for this. I tested out using a different object, but with the same data and you're right it did not match. I'm trying to work out how something like this can be done without having to concat a string together as the key. – n1234 Nov 15 '18 at 21:26