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>