I was trying to swap keys with values in Map and Object.
In Map it goes in an infinite loop, but in Object it goes in a finite loop. I don’t know why is that happening. Please help!
Here is the Code.
const obj = { 1: "one", 2: "two" };
const map = new Map([
[1, "one"],
[2, "two"],
]);
for (const [key, value] of map) { // Goes Infinite Loop
map.set(value, key);
map.delete(key);
}
console.log(map); // you will never get this response
for (const key in obj) { // Goes Finite Loop
const value = obj[key];
obj[value] = key
delete obj[key];
}
console.log(obj); // you will get the response
2
Answers
You mutate the map while iterating thus adding new keys to iterate. So the iteration goes infinite since a new key appears to iterate each iteration cycle. To solve that you need to get a copy of the original keys ahead of the mutation:
As I expected the iterating over keys is potentially faster because there’s no overhead to copy all values:
The reason why your first attempt results in an infinite loop, is because
for...of
is iterating the live contents ofmap
. If you add a new key/value pair it will be placed at the end of the iteration cycle (similar to howarray.push(item)
places the item at the end). This cause an infinite loop.Let’s unroll the loop to show exactly what’s going on.
Like you can see the iteration can never finish, because you keep adding new entries at the end.
To solve this issue all you have to do is to make sure you’re iterating over a non-live collection that doesn’t update whenever you change
map
. This can be done by simply converting the current contents into an array first.This will create the array
[[1, "one"], [2, "two"]]
and iterate over its contents, without it changing during iteration.Alternatively you could also invert
map
by creating a new Map instance.