Как я могу изменить все ключи в словаре, но сохраняя значения? - PullRequest
0 голосов
/ 06 сентября 2018

В моем коде есть словарь, например:

{1: «яблоки», 2: «виноград», 3: «дыни», 4: «бананы», 5: «...», 6: «...», 7: '...'}

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

что я имею в виду: если я уберу 2: "'grapes" ", в словарных ключах будет пробел, где должно быть 2.

моя цель: {1: «яблоки», 2: «дыни», 3: «бананы» 4: «...», 5: «...», 6: '...'}

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

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

спасибо за вашу помощь.

Ответы [ 3 ]

0 голосов
/ 06 сентября 2018

Это массив или объект? Вот как это сделать из Object, и если это Array, просто замените часть значений Array.

Объект:

const obj = { 1: 'a', 2: 'b', 3: 'c' }
const values = Object.values(obj) // [ 'a', 'b', 'c' ]
const newObj = values.reduce((acc, value, i) => {
    acc[i+5] = value // replace i+5 with whatever key you want
    return acc
}, {})
// {5: "a", 6: "b", 7: "c"}

Edit: К сожалению ... Ваш заголовок "Как я могу изменить все ключи в словаре, но сохраняя значения?" и описание хочет, чтобы происходили противоположные вещи.

0 голосов
/ 06 сентября 2018

Думаю, что-то вроде этого должно работать. Вы должны позаботиться о том, чтобы объекты JavaScript не могли иметь числовые ключи (они неявно приводились к строкам).

var dict = {
  1 : 'a',
  2 : 'b',
  3 : 'c',
  4 : 'd',
  5 : 'e'
};//note, that JS objects can't have numeric keys. These will be coerced to strings

function reKeyDict(obj){
  var keys = Object.keys(obj);//get an array of all keys;
  var len = keys.length;
  var greatest = Math.max(...keys);
  keys = keys.sort(function(a,b){ return a - b; });
  for(i = 1; i <= len; i++){//this needs to change if you want zero based indexing.
    if(! keys.includes(i+"")){//we need to coerce to string 
      //we found a gap
      for(var j = i+1, openSlot = i; j <= greatest; j++){
        if(obj[j] !== undefined){
          obj[openSlot++] = obj[j];
          delete obj[j];
        }
      }
    }
  }
}

delete dict['3'];
delete dict['4'];
reKeyDict(dict);
console.log(dict);

Как уже упоминалось .. это действительно не тот случай использования объекта JavaScript. Структура данных, созданная для этого, является массивом. Но ... если вам нужно сделать это таким образом, надеюсь, это поможет.

Приведенный выше код выполняет стабильную операцию (это означает, что порядок вашего исходного объекта сохраняется).

0 голосов
/ 06 сентября 2018

Как вы говорите, это действительно должен быть массив.

Но так как вы, вероятно, знаете индекс, по которому вы удаляете, просто выполните перенумерацию оттуда:

function remove(a, index) {
  while (a.hasOwnProperty(index + 1)) {
    a[index] = a[index + 1];
    ++index;
  }
  delete a[index];
  return a;
}

Live Пример:

function remove(a, index) {
  while (a.hasOwnProperty(index + 1)) {
    a[index] = a[index + 1];
    ++index;
  }
  delete a[index];
  return a;
}

const a = {1: 'apples', 2: 'grapes', 3: 'melons', 4: 'bananas'};
console.log("before:", Object.entries(a).join("; "));

remove(a, 2);
console.log("after:", Object.entries(a).join("; "));

Обратите внимание, что на некоторых движках JavaScript использование delete для объекта значительно замедляет доступ к его свойствам впоследствии. Вместо этого вы можете создать замену объекта:

function remove(a, index) {
  const rv = {};
  let delta = 0;
  for (let n = 1; a.hasOwnProperty(n); ++n) {
    if (n === index) {
      delta = -1;
    } else {
      rv[n + delta] = a[n];
    }
  }
  return rv;
}

function remove(a, index) {
  const rv = {};
  let delta = 0;
  for (let n = 1; a.hasOwnProperty(n); ++n) {
    if (n === index) {
      delta = -1;
    } else {
      rv[n + delta] = a[n];
    }
  }
  return rv;
}

let a = {1: 'apples', 2: 'grapes', 3: 'melons', 4: 'bananas'};
console.log("before:", Object.entries(a).join("; "));

a = remove(a, 2);
console.log("after:", Object.entries(a).join("; "));

Но опять же, на самом деле для этого должна использоваться структура данных, предназначенная для этого: массив:

const a = ['apples', 'grapes', 'melons', 'bananas'];
console.log("before:", Object.entries(a).join("; "));

a.splice(1, 1); // Remove the entry at index 1
console.log("after:", Object.entries(a).join("; "));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...