在地图中的特定索引处插入

Cro*_*csx 3 javascript dictionary typescript

正如文档Map所说:

Map 中的键是有序的,而添加到对象的键则不是。因此,当迭代它时,一个 Map 对象按插入的顺序返回键。

为了充分利用这一点,我需要以Map给定的特定顺序将一个元素插入到 a中。

我知道这可以用数组来完成,但我更喜欢使用 a,Map因为我需要按键进行大量查找,并且 aMap在这种情况下效果很好,同时易于维护。

我想出了这样的事情,我想知道是否有更好的方法来做到这一点。

  function insertAtIndex(index, key, value, map){
    var iterator1 = map[Symbol.iterator]();
    var tmpMap = new Map();
    var tmpIndex=0;
    for (let item of iterator1) {
        if(tmpIndex === index){
            tmpMap.set(key, value);
        }
        tmpMap.set(item[0], item[1]);
        tmpIndex++;
    }
    return tmpMap;
  }
Run Code Online (Sandbox Code Playgroud)

或者

  insertCardAtIndex(index: Number, key: string, value:boardCard, map:Map<string, boardCard>): Map<string, boardCard> {
    let clonedMap = new Map(map);
    let tmpMap = new Map<string, boardCard>();
    let tmpIndex = 0;

    for (let entry of Array.from(clonedMap.entries())) {
      if(tmpIndex === index){
        tmpMap.set(key, value);
      }
      tmpMap.set(entry[0], entry[1]);
      tmpIndex++;
    }

    return tmpMap;
  }
Run Code Online (Sandbox Code Playgroud)

对于我的用例,我将永远不必处理大到足以使性能成为主要关注点的地图,因此如果这使代码更具可读性和可维护性,我愿意牺牲性能。

我正在使用 map 有一个值的“字典”。有没有办法插入特定顺序的元素,这一事实使我不知道我是否应该使用数组来代替,即使有,如快速查找和方法.has().get()以及.set()那些真正有用的,但不值得不是的麻烦能够在某个索引处插入。

luc*_*aro 5

您可以将 the 转换Map为 an Array,用于Array.splice插入元素,然后Map再次转换为 a 。这不是一个有效的解决方案,但您提到在您的用例中,可维护性比性能更重要。

如果您的索引大于地图的大小,此版本的优点是可以工作。例如,在位置插入元素map.size + 1仍会在底部添加项目,在您的算法中不会插入项目。如果您确实想忽略越界的插入,这些插入应该可以通过检查函数轻松解决,但这似乎更健壮。

function insertAtIndex(index, key, value, map){
  const arr = Array.from(map);
  arr.splice(index, 0, [key, value]);
  return new Map(arr);
}

const m = new Map();
m.set('0', 0);
m.set('1', 1);
m.set('2', 2);

console.log(Array.from(m.keys()));

let m2 = insertAtIndex(1, '0.5', 0.5, m);
console.log(Array.from(m2));
m2 = insertAtIndex(0, '-1', -1, m2);
m2 = insertAtIndex(5, '5', 5, m2);
m2 = insertAtIndex(10, '10', 10, m2);

console.log(Array.from(m2));
Run Code Online (Sandbox Code Playgroud)

请注意,与问题本身中的函数类似,上述函数创建并返回一个新的 Map,这意味着对地图的旧引用在插入后失效。如果您假设不变性,这是可以的,但是如果您的代码通常是可变的,并且您可能假设对地图的引用需要保持有效,则需要执行以下操作:

 function insertAtIndex(index, key, value, map){
  const arr = Array.from(map);
  arr.splice(index, 0, [key, value]);
  map.clear();
  arr.forEach(([k,v]) => map.set(k,v));
}

const m = new Map();
m.set('0', 0);
m.set('1', 1);
m.set('2', 2);

console.log(Array.from(m.keys()));

insertAtIndex(1, '0.5', 0.5, m);
insertAtIndex(0, '-1', -1, m);
insertAtIndex(5, '5', 5, m);
insertAtIndex(10, '10', 10, m);

console.log(Array.from(m));
Run Code Online (Sandbox Code Playgroud)