I have an array of objects, where each object has a "children" property (example data below). I want to flatten parents/children into a single array, with each parent immediately followed by it's children.
I've written the following using lo-dash / underscore, and it works when I have one and only one child for each parent:
_.flatten(_.zip(myArr, _.flatten(myArr, "children")))
I know I can use something like _.each and build an object, just wondering if there's a snazzy way to do this using _.
Example Data:
[{
name: "Some Name",
value: 1234,
children: [{
name: "Another name",
value: 3456
}, {
name: "A third name",
value: 9876
}]
}, {
name: "Omg Lazer Guns",
value: 3333,
children: [{
name: "PewPewPew",
value: 4444
}]
}];
A simple and more readable way to do this is
var list = [];
_.each(data, function(item){
list.push(_.omit(item, 'children'));
list.push(_.flatten(_.pick(item, 'children')));
});
var result = _.flatten(list);
The result is
[{
"name": "Some Name",
"value": 1234
}, {
"name": "Another name",
"value": 3456
}, {
"name": "A third name",
"value": 9876
}, {
"name": "Omg Lazer Guns",
"value": 3333
}, {
"name": "PewPewPew",
"value": 4444
}]
The usual approach to merge arrays they way you want to is to zip
them and You can use pluck
to extract the children. Something like this:
var mangled = _(myArr).chain()
.zip(_(myArr).pluck('children'))
.flatten()
.value()
That will leave you with undefined
entries in mangled
if any of the top-level elements of myArr
don't have children
keys at all. You can throw in a compact
to get rid of those:
var mangled = _(myArr).chain()
.zip(_(myArr).pluck('children'))
.flatten()
.compact()
.value()
Demo: http://jsfiddle.net/ambiguous/aeS86/
Of course, doing the mangling with a a couple for
loops and some push
calls will probably be faster but the speed difference shouldn't matter with short arrays.