Reputation: 3520
I am looking to turn this flat array into an nested array but it keeps returning as empty. Not sure how to solve this one or what I am missing but this is driving me crazy.
Flat array:
var names =[
{ name: 'b', parent: 'Brown' },
{ name: 'a', parent: 'Brown' },
{ name: 'h', parent: 'Green' },
{ name: 'c', parent: 'Green' },
];
Desired output of array:
[{
name: 'Brown',
children: [{
name: 'a',
children: []
},
{
name: 'b',
children: []
}
]
}, {
name: 'Green',
children: [{
name: 'h',
children: []
},
{
name: 'c',
children: []
}
]
}
}]
Js:
function getNestedChildren(arr, parent) {
var children = [];
for(var i =0; i < arr.length; ++i) {
if(arr[i].parent == parent) {
var grandChildren = getNestedChildren(arr, arr[i].name)
if(grandChildren.length) {
arr[i].children = grandChildren;
}
children.push( arr[i]);
}
}
return children;
}
var nest = getNestedChildren(names, names.parent);
console.log( nest);
Upvotes: 0
Views: 3176
Reputation: 175
So for starters, you need to loop through the names and send each parent to your getNestedChildren() function.
var names =[
{ name: 'b', parent: 'Brown' },
{ name: 'a', parent: 'Brown' },
{ name: 'h', parent: 'Green' },
{ name: 'c', parent: 'Green' },
];
var nest = [];
for (var i = 0; i < names.length; i++) {
nest.push(getNestedChildren(names, names[i].parent));
}
Also your getNestedChildren() is currently trying to modify and send back the old names array. I'd suggest creating a new object instead and send back the object with the children on it.
function getNestedChildren(arr, parent) {
var children = [];
var parentObj = {};
parentObj.name = parent;
for(var i =0; i < arr.length; ++i) {
if(arr[i].parent == parent) {
children.push(getNestedChildren(arr, arr[i].name));
}
}
parentObj.children = children;
return parentObj;
}
Upvotes: 0
Reputation: 5091
You can create a new object, for each item assign an array to a key with the parent name, and concatenate the item to that array
var names =[
{ name: 'b', parent: 'Brown' },
{ name: 'a', parent: 'Brown' },
{ name: 'h', parent: 'Green' },
{ name: 'c', parent: 'Green' },
];
const getGroup=(groups, parent) => {
let group = groups.find(g=>g.parent===parent);
if(!group){
group=({parent,children:[]});
groups.push(group);
}
return group;
}
let grouped = []
names.forEach(item=> getGroup(grouped,item.parent).children.push(item))
console.log(grouped)
Upvotes: 1
Reputation: 5020
var names =[
{ name: 'b', parent: 'Brown' },
{ name: 'a', parent: 'Brown' },
{ name: 'h', parent: 'Green' },
{ name: 'c', parent: 'Green' },
{ name: 'j', parent: 'Brown' }
];
function groupBy(arr, f) {
return arr.reduce((r, v, i, a, k = f(v)) => ((r[k] || (r[k] = [])).push(v), r), {});
}
function nestArray(array){
var newArray=[],
resultGrouped = groupBy(names, function(c) {
return c.parent
});
for (var key in resultGrouped){
var item=resultGrouped[key];
newArray.push({
name:key,
children:item.map(function(map){
delete map.parent;
map.children=[];
return map;
})
});
}
return newArray;
}
console.log(nestArray(names));
Upvotes: 1