是否可以在不排序的情况下将新元素添加到地图顶部?
像unshift()
一样吗?
因为Map就像一个对象,所以我每次添加操作后都会对对象进行排序。
我这样做是这样的:
let map = new Map();
map.set(1, { id: 1 });
map.set(2, { id: 2 });
map.set(3, { id: 3 });
map.set(4, { id: 4 });
let mapCopy = new Map();
for (let i = map.size; i > 0 ; --i) {
mapCopy.set(i, map.get(i));
}
console.log(map);
console.log(mapCopy);
答案 0 :(得分:1)
Map中的键是有序的。因此,在对其进行迭代时,Map对象将按插入顺序返回键。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
答案 1 :(得分:1)
Map通过指定保留键的插入顺序:
const map = new Map();
map.set(3, "gamma");
map.set(1, "alpha");
map.set(2, "beta");
print(map);
function print(map) {
for ([key, value] of map.entries())
console.log(`${key} - ${value}`)
}
如果您想将某些内容移到末尾,它必须是最后插入的项目。您可以通过删除并重新添加来“移动”:
const map = new Map();
map.set(3, "gamma");
map.set(1, "alpha");
map.set(2, "beta");
moveToEnd(map, 3);
print(map);
function print(map) {
for ([key, value] of map.entries())
console.log(`${key} - ${value}`)
}
//modifies in-place
function moveToEnd(map, key) {
//save value
const value = map.get(key);
//delete
map.delete(key);
//re-insert
map.set(key, value);
}
请注意,您必须删除它,否则它将不起作用:
const map = new Map();
map.set(3, "gamma");
map.set(1, "alpha");
map.set(2, "beta");
moveToEnd(map, 3);
print(map);
function print(map) {
for ([key, value] of map.entries())
console.log(`${key} - ${value}`)
}
//modifies in-place
function moveToEnd(map, key) {
//save value
const value = map.get(key);
//don't delete
//re-insert
map.set(key, value);
}
另一个选择是重新创建整个地图并强制执行新的插入顺序:
const map = new Map();
map.set(3, "gamma");
map.set(1, "alpha");
map.set(2, "beta");
const newMap1 = moveToEnd1(map, 3);
const newMap2 = moveToEnd2(map, 3);
print(newMap1);
console.log("------")
print(newMap2);
function print(map) {
for ([key, value] of map.entries())
console.log(`${key} - ${value}`)
}
function moveToEnd1(map, key) {
//create a new Map from the old one
const result = new Map(map);
//save value
const value = map.get(key);
//delete
result.delete(key);
//re-insert
result.set(key, value);
return result;
}
function moveToEnd2(map, key) {
return [...map.entries()] //get all entries
.filter(([k,]) => k !== key) //remove all but the key that would be last
.reduce( //create a new Map inserting all other entries
(acc, [key, value]) => acc.set(key, value),
new Map()
)
.set(key, map.get(key)); //add the last entry
}
但是,移到最前面意味着您必须将其他所有内容都移到最前面。同样,您可以执行与以前相同的操作-通过删除并重新添加键来就地移动条目:
const map = new Map();
map.set(3, "gamma");
map.set(1, "alpha");
map.set(2, "beta");
const newMap1 = moveToFront(map, 1);
print(map);
function print(map) {
for ([key, value] of map.entries())
console.log(`${key} - ${value}`)
}
function moveToFront(map, key) {
//materialise all entries, because the iterator provides a live view
const entries = Array.from(map.entries());
//move to the back
for (let [k, v] of entries) {
//skip moving the target key
if (k === key) continue;
//delete
map.delete(k);
//re-insert
map.set(k, v);
}
}
或以新顺序重新创建地图。请注意,如果您要在前面插入所需的键,则只需再次使用set
即可,只要不要求使用.delete()
,它就不会移动,这样可以重新创建起来更容易:
const map = new Map();
map.set(3, "gamma");
map.set(1, "alpha");
map.set(2, "beta");
const newMap = moveToFront(map, 1);
print(newMap);
function print(map) {
for ([key, value] of map.entries())
console.log(`${key} - ${value}`)
}
function moveToFront(map, key) {
return new Map([
[key, map.get(key)], //key-value to be in front
...map //merge with the entire map
]);
}
对于实际上添加而不是移动-同样适用,您可以移动地图中的所有内容或重新创建它。假设您要将重复插图视为“向前移动”,则可以执行以下操作:
const map = new Map();
map.set(3, "gamma");
map.set(1, "alpha");
map.set(2, "beta");
addToFrontInPlace(map, 4, "delta");
print(map);
console.log("-------");
addToFrontInPlace(map, 1, "new alpha");
print(map);
function print(map) {
for ([key, value] of map.entries())
console.log(`${key} - ${value}`)
}
function addToFrontInPlace(map, key, value) {
//add new value
map.set(key, value);
//materialise all entries, because the iterator provides a live view
const entries = Array.from(map.entries());
//move to the back
for (let [k, v] of entries) {
//skip moving the target key
if (k === key) continue;
//delete
map.delete(k);
//re-insert
map.set(k, v);
}
}
const map = new Map();
map.set(3, "gamma");
map.set(1, "alpha");
map.set(2, "beta");
const newMap1 = addToFrontNewMap(map, 4, "delta");
print(newMap1);
console.log("-------");
const newMap2 = addToFrontNewMap(newMap1, 1, "new alpha");
print(newMap2);
function print(map) {
for ([key, value] of map.entries())
console.log(`${key} - ${value}`)
}
function addToFrontNewMap(map, key, value = 7) {
//exclude the entry from the old map, so it doesn't overwrite the value
const entries = [...map.entries()]
.filter(([k,]) => k !== key);
return new Map([
[key, value], //key-value to be in front
...entries //merge with the entire map
]);
}