In Map()
with objects as keys is there a way replace/update a key without losing order of entries and if possible, without recreating entire map?
Here is my 3 methods I've tried, the goal is to replace obj2
in the map
with obj4
, maintaining the original order:
const map = new Map(),
obj1 = ["o1"],
obj2 = ["o2"],
obj3 = ["o3"],
obj4 = ["o4"];
map.set(obj1, 1);
map.set(obj2, 2);
map.set(obj3, 3);
console.log("original: " [...map], "expected result: o1,1,o4,2,o3,3");
console.log("1. simple replace object - doesn't work: " [...func1(new Map(map), obj4, obj2)]);
console.log("2. add new and delete old - incorrect order: " [...func2(new Map(map), obj4, obj2)]);
console.log("3. recreate entire map - correct: " [...func3(new Map(map), obj4, obj2)]);
//#1 simple replace object
function func1(map, _new, _old)
{
let obj = map.get(_old);
obj = _new; //doesn't work, because it replaces data in a variable, not in the map itself
return map;
}
//#2 add new and delete old
function func2(map, _new, _old)
{
map.set(_new, map.get(_old));
map.delete(_old)
return map;
}
//#3 recreate entire map
function func3 (map, _new, _old)
{
for(let i = 0, update, entries = [...map]; i < entries.length; i )
{
if (!update && entries[i][0] != _old)
continue;
map.delete(entries[i][0]);
map.set(update ? entries[i][0] : _new, entries[i][1]);
update = true;
}
return map;
}
The #3 works, but maybe there is a more efficient way?
CodePudding user response:
No, Map keys are always iterated over in insertion order. If you add a new key, it'll be added at the end.
The only thing I can think of would be, if you know the shape of both the new and old objects, and they don't have different prototypes (eg, one is an array and the other is an object) is to mutate the existing object.
const map = new Map(),
obj1 = ["o1"],
obj2 = ["o2"],
obj3 = ["o3"],
obj4 = ["o4"];
map.set(obj1, 1);
map.set(obj2, 2);
map.set(obj3, 3);
console.log("original: " [...map], "expected result: o1,1,o4,2,o3,3");
console.log("mutate object: " [...func1(new Map(map), obj4, obj2)]);
function func1(map, newKey, oldKey) {
oldKey.length = 0;
oldKey.push(...newKey);
return map;
}
(for informational purposes only - I wouldn't recommend this when writing serious, easy-to-understand code)