3

I am stuck on a problem trying to change the value of specific properties in a nested array of objects:

const myObj = [
    {
        "Description":"WA State",
        "Data":[
        {
            "Description":"Years",
            "Indicators":[
            {
                "Year":2018,
                "Points":25994,
                "Goal":"28000",
            }
            ]
        },
        {
            "Description":"Local Goal",
            "Indicators":[
            {
                "Year":2018,
                "Points":25994,
                "Goal":"28000",
            }
            ]
        },
        {
            "Description":"Remote Goal",
            "Indicators":[
            {
                "Year":2018,
                "Points":55857,
                "Goal":"84000",
            }
            ]
        }
        ]
    },

    {
        "Description":"NY State",
        "Data":[
        {
            "Description":"Years",
            "Indicators":[
            {
                "Year":2018,
                "Points":21953,
                "Goal":"26000",
            }
            ]
        },
        {
            "Description":"Local Goal",
            "Indicators":[
            {
                "Year":2018,
                "Points":24195,
                "Goal":"25000",
            }
            ]
        },
        {
            "Description":"Remote Goal",
            "Indicators":[
            {
                "Year":2018,
                "Points":80857,
                "Goal":"90000",
            }
            ]
        }
        ]
    }
]

Here I need to change all the appearance of Year property to 2017, and all the appearance of Goal property to: 50000.

I'm thinking in having an array of objects where I can declare something like:

const newValues = [{property: 'Year', newValue: 2019}, {property: 'Goal', newValue: 50000}]

and then use it to compare iterating over the nested array of objects using filter or reduce? Any ideas or suggestions ?

robe007
  • 3,523
  • 4
  • 33
  • 59

2 Answers2

3

To do this recursively and not rely on the parent keys, you might try a combination of mapand forEach.

const myObj = [
  {
    Description: "WA State",
    Data: [
      {
        Description: "Years",
        Indicators: [
          {
            Year: 2018,
            Points: 25994,
            Goal: "28000"
          }
        ]
      },
      {
        Description: "Local Goal",
        Indicators: [
          {
            Year: 2018,
            Points: 25994,
            Goal: "28000"
          }
        ]
      },
      {
        Description: "Remote Goal",
        Indicators: [
          {
            Year: 2018,
            Points: 55857,
            Goal: "84000"
          }
        ]
      }
    ]
  },

  {
    Description: "NY State",
    Data: [
      {
        Description: "Years",
        Indicators: [
          {
            Year: 2018,
            Points: 21953,
            Goal: "26000"
          }
        ]
      },
      {
        Description: "Local Goal",
        Indicators: [
          {
            Year: 2018,
            Points: 24195,
            Goal: "25000"
          }
        ]
      },
      {
        Description: "Remote Goal",
        Indicators: [
          {
            Year: 2018,
            Points: 80857,
            Goal: "90000"
          }
        ]
      }
    ]
  }
];

function parse(arr) {
  return arr.map(obj => {
    Object.keys(obj).forEach(key => {
      if (Array.isArray(obj[key])) {
        parse(obj[key]);
      }
      
      if (key === 'Year') {
        obj[key] = 2017;
      }
      
      if (key === 'Goal') {
        obj[key] = 50000;
      }
    })
    
    return obj;
  })
}

console.log(parse(myObj));
eheisler
  • 124
  • 5
1

An alternative is using nested forEach functions and the function Object.keys to loop over the keys and the function find to get the specific object with the new value to be assigned.

const myObj = [    {        "Description":"WA State",        "Data":[        {            "Description":"Years",            "Indicators":[            {                "Year":2018,                "Points":25994,                "Goal":"28000",            }            ]        },        {            "Description":"Local Goal",            "Indicators":[            {                "Year":2018,                "Points":25994,                "Goal":"28000",            }            ]        },        {            "Description":"Remote Goal",            "Indicators":[            {                "Year":2018,                "Points":55857,                "Goal":"84000",            }            ]        }        ]    },    {        "Description":"NY State",        "Data":[        {            "Description":"Years",            "Indicators":[            {                "Year":2018,                "Points":21953,                "Goal":"26000",            }            ]        },        {            "Description":"Local Goal",            "Indicators":[            {                "Year":2018,                "Points":24195,                "Goal":"25000",            }            ]        },        {            "Description":"Remote Goal",            "Indicators":[            {                "Year":2018,                "Points":80857,                "Goal":"90000",            }            ]        }        ]    }],
      newValues = [{property: 'Year', newValue: 2019}, {property: 'Goal', newValue: 50000}];
      
myObj.forEach(o => {
  o.Data.forEach(d => {
    d.Indicators.forEach(i => {
      Object.keys(i).forEach(k => {
        let nv = newValues.find(n => n.property === k);
        if (nv) i[k] = nv.newValue;
      });
    });
  });
});

console.log(myObj);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ele
  • 33,468
  • 7
  • 37
  • 75