I have a flat array that I'm getting from a MySQL query but I need to convert it into a tree structure. I've been trying to do this for a while now but can't seem to get it done.
It's basically for navigation in a web app. Some nodes will have children but others will not.
I've tried using ES6 array functions like reduce, map, etc but I can't get the child elements to show up.
Here's the structure...
[
{
"page_id": 1,
"page_name": "dashboard",
"path": "/",
"page_icon": "dashboard",
"sub_page_id": 0,
"sub_page_name": null,
"sub_page_path": null,
"sub_page_icon": null,
"parent_id": 0
},
{
"page_id": 2,
"page_name": "Transactions",
"path": "/transactions",
"page_icon": "swap_horiz",
"sub_page_id": 0,
"sub_page_name": null,
"sub_page_path": null,
"sub_page_icon": null,
"parent_id": 0
},
{
"page_id": 6,
"page_name": "Reports",
"path": null,
"page_icon": null,
"sub_page_id": 1,
"sub_page_name": "Transactions Value",
"sub_page_path": "/transactions-value",
"sub_page_icon": "assessment",
"parent_id": 6
},
{
"page_id": 6,
"page_name": "Reports",
"path": null,
"page_icon": null,
"sub_page_id": 2,
"sub_page_name": "Transactions Volume",
"sub_page_path": "/transactions-volume",
"sub_page_icon": "assessment",
"parent_id": 6
},
{
"page_id": 6,
"page_name": "Reports",
"path": null,
"page_icon": null,
"sub_page_id": 3,
"sub_page_name": "Transactions Frequency",
"sub_page_path": "/transactions-frequency",
"sub_page_icon": "assessment",
"parent_id": 6
},
{
"page_id": 8,
"page_name": "Holidays",
"path": null,
"page_icon": null,
"sub_page_id": 7,
"sub_page_name": "My Holidays",
"sub_page_path": "/my-holidays",
"sub_page_icon": "wb_sunny",
"parent_id": 8
},
{
"page_id": 8,
"page_name": "Holidays",
"path": null,
"page_icon": null,
"sub_page_id": 8,
"sub_page_name": "Add User",
"sub_page_path": "/add-user",
"sub_page_icon": "person_add",
"parent_id": 8
},
{
"page_id": 8,
"page_name": "Holidays",
"path": null,
"page_icon": null,
"sub_page_id": 9,
"sub_page_name": "Add Site",
"sub_page_path": "/add-site",
"sub_page_icon": "location_on",
"parent_id": 8
},
{
"page_id": 10,
"page_name": "Logout",
"path": "/logout",
"page_icon": "input",
"sub_page_id": 0,
"sub_page_name": null,
"sub_page_path": null,
"sub_page_icon": null,
"parent_id": 0
}
]
Just off the top of my head, you could use a reduce .
myArray.reduce((acc, curr) => {
if (!curr.sub_page_id)
acc[curr.page_id] = curr
else
acc[curr.page_id].children = acc[curr.page_id].children
? acc[curr.page_id].children[curr.sub_page_id] = curr
: acc[curr.page_id].children = { [sub_page_id]: curr }
return acc
}, {})
I've done it guys. May not be the most efficient method but it works.
const data = response.data;
const tree = [];
data.reduce(function(a, b, i, r) {
// Add the parent nodes
if(a.page_id != b.page_id){
tree.push({ page_id: a.page_id,
page_name: a.page_name,
page_path: a.path,
page_icon: a.page_icon
});
}
// Add the last parent node
if(i+1 == data.length) {
tree.push({ page_id: b.page_id,
page_name: b.page_name,
page_path: b.path,
page_icon: b.page_icon
});
// Add the child nodes to the parent nodes
data.reduce(function(a, b) {
if(a.sub_page_id) {
const find = tree.findIndex(f => f.page_id == a.parent_id);
// Add the first child node to parent
if(!("children" in tree[find])) {
tree[find].children = [];
tree[find].children.push({ page_id: a.sub_page_id,
page_name: a.sub_page_name,
page_path: a.sub_page_path,
page_icon: a.sub_page_icon
});
}
// Add the remaining child nodes to parent nodes
else {
tree[find].children.push({ page_id: a.sub_page_id,
page_name: a.sub_page_name,
page_path: a.sub_page_path,
page_icon: a.sub_page_icon
});
}
}
return b;
});
}
return b;
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.