Home > Blockchain >  How to convert nested object to array of object in javascript?
How to convert nested object to array of object in javascript?

Time:10-28

I have a JSON response from the server, "IN01", "IN02" and "2021", "2022" these are dynamic object keys. I want to covert this structure to some other format. How to do with javascript?

{
  "holidayCalendar": [
    {
      "IN01": [
        {
          "2021": [
            {
              "month": "1",
              "value": "0101111110111011011111101011110"
            },
            {
              "month": "2",
              "value": "1111110111111011111101111110"
            },
            {
              "month": "3",
              "value": "1111110111111011111101111110011"
            }
          ]
        },
        {
          "2022": [
            {
              "month": "4",
              "value": "0011111101111110111111011011101"
            },
            {
              "month": "5",
              "value": "1111101111110111111011111101"
            },
            {
              "month": "6",
              "value": "1111101111110111111011111101111"
            }
          ]
        }
      ]
    },
    {
      "IN02": [
        {
          "2021": [
            {
              "month": "1",
              "value": "0101111110111011011111101011110"
            },
            {
              "month": "2",
              "value": "1111110111111011111101111110"
            },
            {
              "month": "3",
              "value": "1111110111111011111101111110011"
            }
          ]
        },
        {
          "2022": [
            {
              "month": "4",
              "value": "0011111101111110111111011011101"
            },
            {
              "month": "5",
              "value": "1111101111110111111011111101"
            }
          ]
        }
      ]
    }
  ]
}

Here key can be any value instead of "IN01", "IN02" etc also "2021" , "2021"

I want to convert the above JSON data to below-mentioned format

{
    "holidayCalendar" : [
        {
            "location" : "IN01",
            "year" : "2021",
            "holidays" : [
                {
                    "month": "1",
                    "value": "0101111110111011011111101011110"
                  },
                  {
                    "month": "2",
                    "value": "1111110111111011111101111110"
                  },
                  {
                    "month": "3",
                    "value": "1111110111111011111101111110011"
                  }
            ]

        },
        {
            "location" : "IN01",
            "year" : "2022",
            "holidays" : [{
                "month": "4",
                "value": "0011111101111110111111011011101"
              },
              {
                "month": "5",
                "value": "1111101111110111111011111101"
              },
              {
                "month": "6",
                "value": "1111101111110111111011111101111"
              }
            ]
        },
        {
            "location" : "IN02",
            "year" : "2021",
            "holidays" : [
                {
                  "month": "1",
                  "value": "0101111110111011011111101011110"
                },
                {
                  "month": "2",
                  "value": "1111110111111011111101111110"
                },
                {
                  "month": "3",
                  "value": "1111110111111011111101111110011"
                }
              ]

        },
        {
            "location" : "IN02",
            "year" : "2022",
            "holidays" : [
                {
                  "month": "4",
                  "value": "0011111101111110111111011011101"
                },
                {
                  "month": "5",
                  "value": "1111101111110111111011111101"
                }
              ]
        }
    ]
}



Really appreciated your help. Thank You !

CodePudding user response:

You can easily achieve the result using flatMap, Object.entries

const obj = {
  holidayCalendar: [
    {
      IN01: [
        {
          "2021": [
            {
              month: "1",
              value: "0101111110111011011111101011110",
            },
            {
              month: "2",
              value: "1111110111111011111101111110",
            },
            {
              month: "3",
              value: "1111110111111011111101111110011",
            },
          ],
        },
        {
          "2022": [
            {
              month: "4",
              value: "0011111101111110111111011011101",
            },
            {
              month: "5",
              value: "1111101111110111111011111101",
            },
            {
              month: "6",
              value: "1111101111110111111011111101111",
            },
          ],
        },
      ],
    },
    {
      IN02: [
        {
          "2021": [
            {
              month: "1",
              value: "0101111110111011011111101011110",
            },
            {
              month: "2",
              value: "1111110111111011111101111110",
            },
            {
              month: "3",
              value: "1111110111111011111101111110011",
            },
          ],
        },
        {
          "2022": [
            {
              month: "4",
              value: "0011111101111110111111011011101",
            },
            {
              month: "5",
              value: "1111101111110111111011111101",
            },
          ],
        },
      ],
    },
  ],
};

const result = {
  ...obj,
  holidayCalendar: obj.holidayCalendar.flatMap((obj) =>
    Object.entries(obj).flatMap(([location, v]) =>
      v.flatMap((o) =>
        Object.entries(o).map(([year, holidays]) => ({
          location,
          year,
          holidays,
        }))
      )
    )
  ),
};
console.log(result);
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

If you want to use days instead of value then you can do as:

const obj = {
  holidayCalendar: [
    {
      IN01: [
        {
          "2021": [
            {
              month: "1",
              value: "0101111110111011011111101011110",
            },
            {
              month: "2",
              value: "1111110111111011111101111110",
            },
            {
              month: "3",
              value: "1111110111111011111101111110011",
            },
          ],
        },
        {
          "2022": [
            {
              month: "4",
              value: "0011111101111110111111011011101",
            },
            {
              month: "5",
              value: "1111101111110111111011111101",
            },
            {
              month: "6",
              value: "1111101111110111111011111101111",
            },
          ],
        },
      ],
    },
    {
      IN02: [
        {
          "2021": [
            {
              month: "1",
              value: "0101111110111011011111101011110",
            },
            {
              month: "2",
              value: "1111110111111011111101111110",
            },
            {
              month: "3",
              value: "1111110111111011111101111110011",
            },
          ],
        },
        {
          "2022": [
            {
              month: "4",
              value: "0011111101111110111111011011101",
            },
            {
              month: "5",
              value: "1111101111110111111011111101",
            },
          ],
        },
      ],
    },
  ],
};

const result = {
  ...obj,
  holidayCalendar: obj.holidayCalendar.flatMap((obj) =>
    Object.entries(obj).flatMap(([location, v]) =>
      v.flatMap((o) =>
        Object.entries(o).map(([year, holidays]) => ({
          location,
          year,
          holidays: holidays.map(({ value, ...rest }) => ({
            ...rest,
            days: value,
          })),
        }))
      )
    )
  ),
};
console.log(result);
/* This is not a part of answer. It is just to give the output full height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Use Object.keys to get all the keys of the object. Usage example

var json = document.getElementById("json").value;
var jsonObject = JSON.parse(json);

jsonObject.holidayCalendar.forEach(function(x) {
  Object.keys(x).forEach(function(key) {
    console.log(key, x[key]);
  });
})
<textarea id="json">
{
  "holidayCalendar": [
    {
      "IN01": [
        {
          "2021": [
            {
              "month": "1",
              "value": "0101111110111011011111101011110"
            },
            {
              "month": "2",
              "value": "1111110111111011111101111110"
            },
            {
              "month": "3",
              "value": "1111110111111011111101111110011"
            }
          ]
        },
        {
          "2022": [
            {
              "month": "4",
              "value": "0011111101111110111111011011101"
            },
            {
              "month": "5",
              "value": "1111101111110111111011111101"
            },
            {
              "month": "6",
              "value": "1111101111110111111011111101111"
            }
          ]
        }
      ]
    },
    {
      "IN02": [
        {
          "2021": [
            {
              "month": "1",
              "value": "0101111110111011011111101011110"
            },
            {
              "month": "2",
              "value": "1111110111111011111101111110"
            },
            {
              "month": "3",
              "value": "1111110111111011111101111110011"
            }
          ]
        },
        {
          "2022": [
            {
              "month": "4",
              "value": "0011111101111110111111011011101"
            },
            {
              "month": "5",
              "value": "1111101111110111111011111101"
            }
          ]
        }
      ]
    }
  ]
}
</textarea>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related