I have an original array and I want to plot it in Sunburst map which needs a hierarchical data structure.
[
{id: "Asia,India,NewDelhi", value: 41},
{id: "Europe,Germany,Berlin", value: 24},
{id: "Europe,England,London", value: 3},
{id: "NorthAmerica,USA,NewYork", value: 4},
{id: "NorthAmerica,USA,Boston", value: 3},
{id: "NorthAmerica,USA,chicago", value: 3},
{id: "Austrailia,Sydney", value: 4},
{id: "Asia,China,Beijing", value: 2},
]
Desired Result
[
{
id: Asia,
children:[{
id: India,
children:[{
id: Delhi,
value: 41,
}]
},
{
id:China,
children:[{
id: Beijing
value: 2,
}]
}]
},
{
id: Europe,
children: [{
id: Germany,
children: [{
id: Berlin,
value: 24,
}]
},
{
id: England,
children: [{
id: London,
value: 3,
}]
}]
},
{
id: NorthAmerica,
children:[{
id: USA,
children:[{
id: NewYork,
value: 4,
},
{
id: Boston,
value: 3,
},
{
id: Chicago,
value: 3,
}]
}]
},
{
id: Austrailia
children: [{
id:Sydney,
value: 4,
}]
},
]
can anyone help me with this, I tried using reduce method but I am not able to get the desired result.
PS : It would be super useful if anyone could suggest an answer that would deal with n number of ids separated by commas. For ex: here we have 3 id hierarchy separated by commas, what would happen if there were 4 or 5 depth data.
To build a hierarchy of objects from your input is fairly straightforward, you dont even need to do anything recursive a loop + reduce
will do it. This will work with any number of levels in your comma separated list.
const input = [
{id: "Asia,India,NewDelhi", value: 41},
{id: "Europe,Germany,Berlin", value: 24},
{id: "Europe,England,London", value: 3},
{id: "NorthAmerica,USA,NewYork", value: 4},
{id: "NorthAmerica,USA,Boston", value: 3},
{id: "NorthAmerica,USA,chicago", value: 3},
{id: "Austrailia,Sydney", value: 4},
{id: "Asia,China,Beijing", value: 2}
]
const result = input.map(o => ({ids:o.id.split(","), value:o.value})).reduce( (acc,obj) => {
let curr = acc;
let id;
while( (id = obj.ids.shift()) != null ){
if(!curr[id])
curr[id] = {};
curr = curr[id];
}
curr.value = obj.value
return acc;
},{});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
To then turn this into the format you wanted does take a bit of recursion:
const input = [
{id: "Asia,India,NewDelhi", value: 41},
{id: "Europe,Germany,Berlin", value: 24},
{id: "Europe,England,London", value: 3},
{id: "NorthAmerica,USA,NewYork", value: 4},
{id: "NorthAmerica,USA,Boston", value: 3},
{id: "NorthAmerica,USA,chicago", value: 3},
{id: "Austrailia,Sydney", value: 4},
{id: "Asia,China,Beijing", value: 2}
]
const result = input.map(o => ({ids:o.id.split(","), value:o.value})).reduce( (acc,obj) => {
let curr = acc;
let id;
while( (id = obj.ids.shift()) != null ){
if(!curr[id])
curr[id] = {};
curr = curr[id];
}
curr.value = obj.value
return acc;
},{});
function buildHierarchy(input){
return Object.entries(input).map( ([id,children]) => {
if(children.value){
return {id,value:children.value}
}
return {id, children: buildHierarchy(children)}
})
}
console.log(buildHierarchy(result));
.as-console-wrapper { max-height: 100% !important; top: 0; }