Вставить по определенному индексу на карте - PullRequest
0 голосов
/ 10 ноября 2018

Как указано в документации для Map:

Ключи в Map упорядочены, а ключи, добавленные в объект, - нет.Таким образом, при итерации по нему объект Map возвращает ключи в порядке вставки.

Чтобы в полной мере воспользоваться этим, мне нужно вставить элемент в Map в заданном конкретном порядке.

Я знаю, что это можно сделать с помощью массива, но я предпочитаю использовать Map, потому что мне нужно много раз искать по ключу, и Map хорошо работает в этом случае, будучипрост в обслуживании.

Я придумал что-то подобное и хотел бы знать, есть ли более эффективные способы сделать это.

  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;
  }

или

  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;
  }

В моем случае использования мне никогда не придется иметь дело с картой, достаточно большой, чтобы сделать производительность основной проблемой, поэтому я готов пожертвовать производительностью, если это сделает код более читабельным и обслуживаемым.

Я использую карту имеет «словарь» значений по.Тот факт, что нет способа вставить элемент в определенном порядке, заставляет меня задуматься, стоит ли мне вместо этого использовать массив, несмотря на быстрый поиск и такие методы, как .has(), .get() и .set(), которые действительнополезно, но не стоит того, чтобы не вставлять по определенному индексу.

1 Ответ

0 голосов
/ 10 ноября 2018

Вы можете преобразовать Map в Array, использовать Array.splice, чтобы вставить элемент, а затем снова преобразовать в Map. Это неэффективное решение , но вы упомянули, что удобство обслуживания важнее, чем производительность в вашем случае использования.

Эта версия имеет преимущество в работе, если ваш индекс больше, чем размер карты. Например, вставка элемента в положение 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));

Обратите внимание, что, аналогично функциям самого вопроса, вышеуказанная функция создает и возвращает новую карту, что означает, что старые ссылки на карту становятся недействительными после вставки. Это нормально, если вы предполагаете неизменность, но если ваш код обычно изменчив, и вы можете считать, что ссылки на карту должны оставаться действительными, вам нужно сделать что-то вроде следующего:

 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));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...