Reputation: 6312
I have an array of objects that contains all my routes. I need to access all object's nested children properties & their properties and combining the together.
My array of object looks similar to this:
const routes = [
{
path: '/system-settings1',
name: 'global-settings1',
component: 'tabs1',
children: [
{
path: 'level2-accounting1',
name: 'local-settings1',
components: 'modals1',
children: [
{
path: 'level3-accounting1',
name: 'local-settings1',
components: 'modals1'
}
// more children deeply nested(or not)
]
},
{
path: 'level2-accounting1',
name: 'local-settings1',
components: 'modals1',
children: [
{
path: 'level3-accounting1',
name: 'local-settings1',
components: 'modals1'
}
// more children deeply nested(or not)
]
}
],
},
{
path: '/system-settings2',
name: 'global-settings2',
component: 'tabs2',
children: [
{
path: 'level2-accounting2',
name: 'local-settings2',
components: 'modals2',
children: [
{
path: 'level3-accounting2',
name: 'local-settings2',
components: 'modals2'
}
// more children deeply nested(or not)
]
},
{
path: 'level3-accounting2',
name: 'local-settings2',
components: 'modals2',
children: [
{
path: 'level4-accounting2',
name: 'local-settings2',
components: 'modals2'
}
// more children deeply nested(or not)
],
}
],
},
// more objects with similar key/value pairs
];
I need to make the array of objects into single level array flat like so:
[
{
path: '/system-settings1',
name: 'global-settings1',
component: 'tabs1',
},
{
path: 'level2-accounting2',
name: 'local-settings2',
components: 'modals2',
},
{
path: 'level3-accounting1',
name: 'local-settings1',
components: 'modals1'
},
{
path: 'level2-accounting1',
name: 'local-settings1',
components: 'modals1',
}
// so on if there is more objects etc
]
I have tried to .map()
& .filter()
combine with a while
loop, but to be honest I'm lacking the skills to accomplish by my own & it's not worth to include my attempts. If anybody could assist me with this & explain it would be extremely appreciated.
Upvotes: 0
Views: 261
Reputation: 50787
Here's a pretty straightforward ES6 function. It is perhaps not the most performant version available, but it's simple.
const flattenAll = (xs) => xs .reduce (
(all, {children, ...rest}) => [...all, {...rest}, ...flattenAll(children || [])],
[]
)
const routes = [{path: "/system-settings1", name: "global-settings1", component: "tabs1", children: [{path: "level2-accounting1", name: "local-settings1", components: "modals1", children: [{path: "level3-accounting1", name: "local-settings1", components: "modals1"}]}, {path: "level2-accounting1", name: "local-settings1", components: "modals1", children: [{path: "level3-accounting1", name: "local-settings1", components: "modals1"}]}]}, {path: "/system-settings2", name: "global-settings2", component: "tabs2", children: [{path: "level2-accounting2", name: "local-settings2", components: "modals2", children: [{path: "level3-accounting2", name: "local-settings2", components: "modals2"}]}, {path: "level3-accounting2", name: "local-settings2", components: "modals2", children: [{path: "level4-accounting2", name: "local-settings2", components: "modals2"}]}]}];
console .log (flattenAll (routes))
Note that this uses a depth-first ordering; I'm guessing that a breadth-first one would be significantly uglier code, but I haven't tried it.
Upvotes: 1
Reputation: 579
I tried to edit your code examples so that they made sense and ran without errors. This is a recursive function that gets called on the root routes
array, as well as any nested children
arrays:
const flatten = routes => {
const flattened = [];
for (let i = 0; i < routes.length; i++) {
const route = routes[i];
//for each route, grab only the information about the route itself (no children)
const { path, name, components } = route;
const flatRoute = { path, name, components };
//add the new route object to our return array
flattened.push(flatRoute);
//if the route had children, recursively call flatten on them
//and add each child to our return array
if (route.children) {
const flatChildren = flatten(route.children);
flattened.push(...flatChildren);
}
}
return flattened;
};
Upvotes: 1