简体   繁体   中英

Change value of a nested key value in javascript

I'm trying to change an specific value in a nested key value structure, but when I set a value it changes all key's value.

Initial data is:

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

I want to change the value of an specific path

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

But the result is wrong. Because it changes:

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

Final result:

    {
      "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]
          ]
        }
      }
    }

Source code: https://playcode.io/301552?tabs=console&script.js&output

Check this section of the 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;
}

Using for (const runner of runners) {data[runner] = marketData;} you are storing multiple references to the same object. That is a problem.

One possible solution is to change marketData to a method that generate a new object every time is called. Example:

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

New version: https://playcode.io/301583?tabs=console&script.js&output

Yeah, @Shidersz is right. I also checked because when I tried from the Node terminal, I couldn't see any issue as the object you have pasted in the problem is the one created by function (So it works fine).

> 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 ]
> 

I thought, what is happening then. Finally, I checked your code which is creating data . There you're referencing the same object for different keys.

So, updating a single one is like affecting others but internally they are just references to a same memory location where the real object is stored.

This What is the most efficient way to deep clone an object in JavaScript? would be really very very helpful for you to understand the concept of Deep & Shallow copy of variables.

Finally you can check the updated code at https://playcode.io/301586?tabs=console&script.js&output . I have just copied the outer marketData and placed inside for loop.

That is it. Thank you v. much.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM