Изменить значение вложенного ключа в JavaScript - PullRequest
2 голосов
/ 27 апреля 2019

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

Исходные данные:

   const data = {
      "1.157685561": {
        "1222344": {
          "batb": [
            [0, 0],
            [0, 0],
            [0, 0]
          ],
          "batl": [
            [0, 0],
            [0, 0],
            [0, 0]
          ]
        },
        "1222345": {
          "batb": [
            [0, 0],
            [0, 0],
            [0, 0]
          ],
          "batl": [
            [0, 0],
            [0, 0],
            [0, 0]
          ]
        }
      }
    }

Я хочу изменить значение определенного пути

    data['1.157685561']['1222344']['batl'][0] = [1,2]

Но результат неправильный.Потому что он меняется:

  • data['1.157685561']['1222344']
  • data['1.157685561']['1222345']

Окончательный результат:

    {
      "1.157685561": {
        "1222344": {
          "batb": [
            [0, 0],
            [0, 0],
            [0, 0]
          ],
          "batl": [
            [1, 2],
            [0, 0],
            [0, 0]
          ]
        },
        "1222345": {
          "batb": [
            [0, 0],
            [0, 0],
            [0, 0]
          ],
          "batl": [
            [1, 2],
            [0, 0],
            [0, 0]
          ]
        }
      }
    }

Исходный код: https://playcode.io/301552?tabs=console&script.js&output

Ответы [ 2 ]

3 голосов
/ 27 апреля 2019

Проверьте этот раздел предоставленного кода :

function createEmptyMarketData(runners) {
    const data = {};
    const marketData = {
        batb: [
          [0, 0],
          [0, 0],
          [0, 0]
        ],
        batl: [
          [0, 0],
          [0, 0],
          [0, 0]
        ]
    };

    for (const runner of runners) {
        data[runner] = marketData;
    }

    return data;
}

Используя for (const runner of runners) {data[runner] = marketData;}, вы храните несколько ссылок на один и тот же объект. Это проблема.

Одним из возможных решений является изменение marketData на метод, который генерирует новый object каждый раз, когда вызывается. Пример:

function createEmptyMarketData(runners)
{
    const data = {};

    const marketData = () => ({
        batb: [[0, 0], [0, 0], [0, 0]],
        batl: [[0, 0], [0, 0], [0, 0]]
    });

    for (const runner of runners)
    {
        data[runner] = marketData();
    }

    return data;
}

Новая версия: https://playcode.io/301583?tabs=console&script.js&output

1 голос
/ 27 апреля 2019

Да, @Shidersz прав.Я также проверил, потому что, когда я пытался из терминала Node, я не мог видеть никакой проблемы, так как объект, который вы вставили в проблему, это тот, который создан функцией (так что он работает нормально).

> const data = {
...       "1.157685561": {
.....         "1222344": {
.......           "batb": [
.......             [0, 0],
.......             [0, 0],
.......             [0, 0]
.......           ],
.......           "batl": [
.......             [0, 0],
.......             [0, 0],
.......             [0, 0]
.......           ]
.......         },
.....         "1222345": {
.......           "batb": [
.......             [0, 0],
.......             [0, 0],
.......             [0, 0]
.......           ],
.......           "batl": [
.......             [0, 0],
.......             [0, 0],
.......             [0, 0]
.......           ]
.......         }
.....       }
...     }
undefined
> 
> data['1.157685561']['1222344']['batl'][0] = [1,2]
[ 1, 2 ]
> 
> data
{ '1.157685561':
   { '1222344': { batb: [Array], batl: [Array] },
     '1222345': { batb: [Array], batl: [Array] } } }
> 
> data['1.157685561']['1222344']['batl'][0]
[ 1, 2 ]
> 
> data['1.157685561']['1222345']['batl'][0]
[ 0, 0 ]
> 

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

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

Это Что такоесамый эффективный способ глубокого клонирования объекта в JavaScript? было бы действительно очень полезно для понимания концепции глубокой и мелкой копии переменных.

Наконец, вы можете проверить обновленный кодв https://playcode.io/301586?tabs=console&script.js&output. Я только что скопировал внешние marketData и поместил их внутрь для цикла.

Вот и все.Большое спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...