Search code examples
javascriptreactjsgraphqlapollo

How to convert nested object to array of object in javascript?


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 !


Solution

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

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