Reputation: 109
Any suggestions on how to get nested arrays / objects from the following array of objects?
[
{COLOR: "Black", FABRIC_DESIGN: "Leather", SIZE: "S"}
{COLOR: "Black", FABRIC_DESIGN: "Leather", SIZE: "L"}
{COLOR: "Black", FABRIC_DESIGN: "Velvet", SIZE: "S"}
{COLOR: "Black", FABRIC_DESIGN: "Velvet", SIZE: "M"}
{COLOR: "Red", FABRIC_DESIGN: "Velvet", SIZE: "S"}
]
What I am trying to get is:
[
{
label: "Black",
children: [
{ label: "Leather", children: [{ label: "S" }, { label: "L" }] },
{ label: "Velvet", children: [{ label: "S" }, { label: "M" }] }
]
},
{
label: "Red",
children: [{ label: "Velvet", children: [{ label: "S" }] }]
}
];
I managed to do it for objects with 2 properties but not more than that, and I cant figure out how to do it for objects with N properties.
Upvotes: 1
Views: 1101
Reputation: 497
EDIT : Now, you can specify the hierarchy.
var data = [
{COLOR: "Black", FABRIC_DESIGN: "Leather", SIZE: "S"},
{COLOR: "Black", FABRIC_DESIGN: "Leather", SIZE: "L"},
{COLOR: "Black", FABRIC_DESIGN: "Velvet", SIZE: "S"},
{COLOR: "Black", FABRIC_DESIGN: "Velvet", SIZE: "M"},
{COLOR: "Red", FABRIC_DESIGN: "Velvet", SIZE: "S"}
]
var hierarchy = ['COLOR', 'FABRIC_DESIGN', 'SIZE'];
// temporary object to make uniqu entries
var structuredDatas = {};
data.forEach(el => {
var editedDatas = structuredDatas;
for (depth of hierarchy) {
if (typeof el[depth] === 'undefined') {
break;
}
if (!editedDatas[el[depth]]) {
editedDatas[el[depth]] = { label: el[depth], children: {} };
}
editedDatas = editedDatas[el[depth]].children;
}
});
// all data are structured
// next, we format data as expected
var formattedDatas = Object.values(structuredDatas).map(formatLevel)
function formatLevel(datas) {
datas.children = Object.values(datas.children).map(formatLevel)
return datas
}
console.log(JSON.stringify(formattedDatas, null, 2));
Upvotes: 0
Reputation: 122027
You could do this using reduce
and forEach
methods and one object to keep the data of each level.
const data = [{COLOR: "Black", FABRIC_DESIGN: "Leather", SIZE: "S"},{COLOR: "Black", FABRIC_DESIGN: "Leather", SIZE: "L"},{COLOR: "Black", FABRIC_DESIGN: "Velvet", SIZE: "S"},{COLOR: "Black", FABRIC_DESIGN: "Velvet", SIZE: "M"},{COLOR: "Red", FABRIC_DESIGN: "Velvet", SIZE: "S"}]
const result = []
const levels = {result}
const keys = ['COLOR', 'FABRIC_DESIGN', 'SIZE']
data.forEach(o => {
keys.reduce((r, k, i, a) => {
const label = o[k];
if (!r[label]) {
const value = {label}
if (a[i + 1]) {
r[label] = {result: []}
value.children = r[label].result
}
r.result.push(value)
}
return r[label]
}, levels)
})
console.log(result)
Upvotes: 1