I am trying to solve this question it needs me to flatten this object parent
that it has children
each parent has 2 children, and each child has 2 children and so on....
My goal is to flatten this to one single object.
const par = {
id: 1,
name: "parent",
children: [{
id: 2,
name: "child 1",
children:[{
id: 4,
name: "child 3",
children: [],
},{
id: 5,
name: "child 4 ",
}]
},{
id: 3,
name: "child 2",
children: [{
id: 6,
name: "child 5",
},{
id: 7,
name: "child 6",
children: []
}]
}]
}
I tried function, but it returns an array from Deep Flatten JavaScript Object Recursively
function flat(r, a) {
let b = {};
Object.keys(a).forEach(function (k) {
if (k !== 'children') {
b[k] = a[k];
}
});
r.push(b);
if (Array.isArray(a.children)) {
b.children = a.children.map(function (a) { return a.id;});
return a.children.reduce(flat, r);
}
return r;
}
CodePudding user response:
Here's an effective technique using a recursive generator flat
-
function *flat({ children = [], ...t }, parentId = null) {
yield { ...t, parentId }
for (const child of children)
yield *flat(child, t.id)
}
const par = {id: 1,name: "parent",children: [{id: 2,name: "child 1",children:[{id: 4,name: "child 3",children: [],},{id: 5,name: "child 4 ",}]},{id: 3,name: "child 2",children: [{id: 6,name: "child 5",},{id: 7,name: "child 6",children: []}]}]}
console.log(Array.from(flat(par)))
.as-console-wrapper { min-height: 100%; top: 0; }
You can collect all the results of a generator using Array.from
-
[
{
"id": 1,
"name": "parent",
"parentId": null
},
{
"id": 2,
"name": "child 1",
"parentId": 1
},
{
"id": 4,
"name": "child 3",
"parentId": 2
},
{
"id": 5,
"name": "child 4 ",
"parentId": 2
},
{
"id": 3,
"name": "child 2",
"parentId": 1
},
{
"id": 6,
"name": "child 5",
"parentId": 3
},
{
"id": 7,
"name": "child 6",
"parentId": 3
}
]
Or you can simply iterate thru the generator's result directly -
for (const flatNode of flat(par)) {
// do something with flatNode ...
}
See this related Q&A for a technique to convert the flat tree back to a recursive tree or graph.
CodePudding user response:
You can try this
function flatTree(tree, parentId = null) {
const { id, name, children } = tree;
const result = [{ id, name, parentId }];
if (Array.isArray(children)) {
children.forEach((child) => {
result.push(...flatTree(child, id));
});
}
return result;
}
const par = {
id: 1,
name: "parent",
children: [
{
id: 2,
name: "child 1",
children: [
{
id: 4,
name: "child 3",
children: [],
},
{
id: 5,
name: "child 4 ",
},
],
},
{
id: 3,
name: "child 2",
children: [
{
id: 6,
name: "child 5",
},
{
id: 7,
name: "child 6",
children: [],
},
],
},
],
};
console.log(flatTree(par));
/**
* Output:
* [
{ id: 1, name: 'parent', parentId: null },
{ id: 2, name: 'child 1', parentId: 1 },
{ id: 4, name: 'child 3', parentId: 2 },
{ id: 5, name: 'child 4 ', parentId: 2 },
{ id: 3, name: 'child 2', parentId: 1 },
{ id: 6, name: 'child 5', parentId: 3 },
{ id: 7, name: 'child 6', parentId: 3 }
]
*/
CodePudding user response:
You still owe us a description of your desired output. But if you want something as simple as this:
[
{id: 1, name: "parent"},
{id: 2, name: "child 1"},
{id: 4, name: "child 3"},
{id: 5, name: "child 4"},
{id: 3, name: "child 2"},
{id: 6, name: "child 5"},
{id: 7, name: "child 6"}
]
Then a depth-first recursive function can be as simple as this:
const flatten = ({children = [], ...rest}) => [rest, ...children .flatMap (flatten)]
const par = {id: 1, name: "parent", children: [{id: 2, name: "child 1", children: [{id: 4, name: "child 3", children: []}, {id: 5, name: "child 4 ", }]}, {id: 3, name: "child 2", children: [{id: 6, name: "child 5", }, {id: 7, name: "child 6", children: []}]}]}
console .log (flatten (par))
.as-console-wrapper {max-height: 100% !important; top: 0}
If you wanted to include a parentId
field, using null
for root-level objects, it's only slightly more complex:
const flatten = ({id, children = [], ...rest}, parentId = null) => [
{id, ...rest, parentId}, ...children .flatMap (c => flatten(c, id))
]