在javascript中更改嵌套键值的值

时间:2019-04-27 03:27:45

标签: javascript arrays dictionary key-value

我试图更改嵌套键值结构中的特定值,但是当我设置一个值时,它会更改所有键值。

初始数据为:

   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 个答案:

答案 0 :(得分:3)

检查provided code的本部分:

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 :(得分:1)

是的,@ Shidersz是正确的。我还进行了检查,因为当我从Node终端尝试时,我看不到任何问题,因为您粘贴到问题中的对象是由函数创建的对象(因此可以正常工作)。

wrap_content

我想,那是怎么回事。最后,我检查了您的代码,该代码正在创建数据。在那里,您为不同的键引用同一对象。

因此,更新单个对象就像影响其他对象一样,但是在内部,它们只是对存储实际对象的同一内存位置的引用。

  

这个What is the most efficient way to deep clone an object in JavaScript?对于您理解变量的深层和浅层副本的概念非常有帮助。

最后,您可以在https://playcode.io/301586?tabs=console&script.js&output上查看更新的代码。我刚刚复制了外部 marketData 并将其放入for循环中。

就是这样。非常感谢。