I have 2 types of a objects, a group
, and an item
. A group can have children
which is either an array of groups
or an array of items
.
I've ended up with a series of nested groups (which can be infinite levels deep) and I need to retrieve all the items, no matter how many levels deep, with only a group to work with.
Is there a way to retrieve all the items from the top-level group in the following data structure?
{
type: 'group',
children: [
{
type: 'group',
children: [
{
type: 'group',
children: [{type:'item'}, {type:'item'}, {type:'item'}]
},
{
type: 'group',
children: [{type:'item'}, {type:'item'}, {type:'item'}]
},
{
type: 'group',
children: [{type:'item'}, {type:'item'}, {type:'item'}]
},
]
},
{
type: 'group',
children: [
{
type: 'group',
children: [{type:'item'}]
},
{
type: 'group',
children: [{type:'item'}]
},
{
type: 'group',
children: [{type:'item'}]
},
]
},
{
type: 'group',
children: [
{
type: 'group',
children: [{type:'item'}, {type:'item'}]
},
{
type: 'group',
children: [{type:'item'}, {type:'item'}]
},
{
type: 'group',
children: [{type:'item'}, {type:'item'}]
},
]
},
]
}
I have 2 types of a objects, a group
, and an item
. A group can have children
which is either an array of groups
or an array of items
.
I've ended up with a series of nested groups (which can be infinite levels deep) and I need to retrieve all the items, no matter how many levels deep, with only a group to work with.
Is there a way to retrieve all the items from the top-level group in the following data structure?
{
type: 'group',
children: [
{
type: 'group',
children: [
{
type: 'group',
children: [{type:'item'}, {type:'item'}, {type:'item'}]
},
{
type: 'group',
children: [{type:'item'}, {type:'item'}, {type:'item'}]
},
{
type: 'group',
children: [{type:'item'}, {type:'item'}, {type:'item'}]
},
]
},
{
type: 'group',
children: [
{
type: 'group',
children: [{type:'item'}]
},
{
type: 'group',
children: [{type:'item'}]
},
{
type: 'group',
children: [{type:'item'}]
},
]
},
{
type: 'group',
children: [
{
type: 'group',
children: [{type:'item'}, {type:'item'}]
},
{
type: 'group',
children: [{type:'item'}, {type:'item'}]
},
{
type: 'group',
children: [{type:'item'}, {type:'item'}]
},
]
},
]
}
Share
Improve this question
edited Mar 3, 2017 at 11:34
Ryan King
asked Mar 3, 2017 at 11:11
Ryan KingRyan King
3,69612 gold badges50 silver badges73 bronze badges
4
- 1 your data structure is not valid. arrays have no property in a literal. – Nina Scholz Commented Mar 3, 2017 at 11:13
- if you make it correct then use recursion tech to cater this. – Jai Commented Mar 3, 2017 at 11:15
- As you won't have property labels available to you in an actual array, how will you differentiate between an array of group objects and array of item objects? If you can show an example of an actual array and include the group and item object definitions this might be easier. – Nope Commented Mar 3, 2017 at 11:18
- btw, what qualifies a deep node? or would you like to get all nodes? – Nina Scholz Commented Mar 3, 2017 at 11:19
2 Answers
Reset to default 7You could use an iterative with Array#reduce
and recursive with calling iter
again, approach.
var data = { children: [{ children: [{ children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }, { children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }, { children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }] }, { children: [{ children: [{ name: 'item1' }] }, { children: [{ name: 'item1' }] }, { children: [{ name: 'item1' }] }] }, { children: [{ children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }, { children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }, { children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }] }] }] },
children = [data].reduce(function iter(r, a) {
if (Array.isArray(a.children)) {
return a.children.reduce(iter, r);
}
r.push(a);
return r;
}, []);
console.log(children);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can achieve it with recursion.
var data = {
children: [
{
children: [
{
children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
},
{
children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
},
{
children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
}
]
},
{
children: [
{
children: [{ name: 'item1' }]
},
{
children: [{ name: 'item1' }]
},
{
children: [{ name: 'item1' }]
}
]
},
{
children: [
{
children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
},
{
children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
},
{
children: [{ name: 'item1' }, { name: 'item2' }, { name: 'item3' }]
}
]
}
]
};
function getAllChildren(group, children) {
children = children || [];
if(group && Array.isArray(group.children)) {
group.children.forEach(function(child) {
getAllChildren(child, children)
});
}
else {
children.push(group);
}
return children;
}
console.log(getAllChildren(data));