0

When I run the following code:

fake_key = new Set([{v: 1, w: 2}])
fake_memo = {};
fake_memo[fake_key] = 2;

fake_key = new Set([{v: 5, w: 5}])
fake_memo[fake_key] = 5;

And then print or log fake_memo, I expect to see:

{ '[object Set]': 2, '[object Set]': 5 }

Instead I get:

{ '[object Set]': 5 }

As if the first object I inserted into the object map got clobbered by the second.

Why does this occur? How do I recover the behavior I want (both keys being inserted into the map)?

2
  • 3
    objects have strings as keys. the set is converted to string, which is '[object Set]'. Commented Aug 14, 2018 at 16:58
  • 1
    Use a Map for that. In JS object keys are also strings, no exception, js objects are not hashmaps. Commented Aug 14, 2018 at 17:04

2 Answers 2

3

Property keys of plain objects are always strings. Your sets are being converted to strings, which always gives the string "[object Set]".

You can instead use a Map instance instead of a plain object, because Map keys can be any type of value. To do that, make a map:

fake_memo = new Map();

then

fake_memo.set(fake_key, 2);

etc. Use

var value = fake_memo.get(some_key);

to retrieve values.

You can use ordinary [ ] operations on a Map instance, but that will still treat the Map as an ordinary object.

Sign up to request clarification or add additional context in comments.

5 Comments

The behavior is unchanged if I change to fake_memo = new Map();, unfortunately. More specifically, I now see Map { '[object Set]': 5 }.
Ah well you have to use the Map API to set and get values by key; I'll extend the answer.
So Map.set and Map.get differ in behavior from Map[accessor] = foo? Wat?
@AlekseyBilogur yes, which is disturbing. You could use the Proxy feature to work around that, but depending on your point of view that might be more confusing than the default behavior. I haven't done a lot of work with either Set or Map so my opinion isn't worth much on that :)
I'm accepting this answer because it's clearly the correct one, but what a gotcha this API is!
1

As another answer said, keys can only be strings. So this may be what you are looking for:

fake_key = JSON.stringify(Array.from(new Set([{v: 1, w: 2}])));
fake_memo = {};
fake_memo[fake_key] = 2;

fake_key = JSON.stringify(Array.from(new Set([{v: 5, w: 5}])));
fake_memo[fake_key] = 5;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.