I need to generate a flat array of objects containing all ancestors of a given object in a flat normalized array of objects.
Lots of examples exist for turning it into a nested tree like structure, but I haven't been able to find any info for simply returning all ancestors in a flat array. Each object in the flat normalized array has an id and a parentId.
Given a flat normalized array of objects
[
{
id: 1,
name: "node 1",
parentId: null,
}, {
id: 2,
name: "node 2",
parentId: 1,
}, {
id: 3,
name: "node 3",
parentId: null,
}, {
id: 4,
name: "node 4",
parentId: 3,
}, {
id: 5,
name: "node 5",
parentId: 2,
}, {
id: 6,
name: "node 6",
parentId: 1,
}, {
id: 7,
name: "node 7",
parentId: 6,
},
]
When doing getAncestors(1)
it should return all ancestors of node 1
[
{
id: 2,
name: "node 2",
parentId: 1,
}, {
id: 5,
name: "node 5",
parentId: 2,
}, {
id: 6,
name: "node 6",
parentId: 1,
}, {
id: 7,
name: "node 7",
parentId: 6,
},
]
I've tried modifying the functions for turning it into a nested tree like structure, but without luck.
For a faaster access, you need a Map
with all nodes and their id
as key as well as a map for all parents with parentId
as key. Then you need the function getAncestors
and inside, you need a function for getting a nod an it's ancestors as well.
Combine all with a reducing and return the result.
function getAncestors(parentId) { const getNode = node => [node, ...getAncestors(node.id)]; return (parents.get(parentId) || []).reduce((r, id) => [...r, ...getNode(nodes.get(id))], []); } var data = [{ id: 1, name: "node 1", parentId: null, }, { id: 2, name: "node 2", parentId: 1 }, { id: 3, name: "node 3", parentId: null }, { id: 4, name: "node 4", parentId: 3 }, { id: 5, name: "node 5", parentId: 2 }, { id: 6, name: "node 6", parentId: 1 }, { id: 7, name: "node 7", parentId: 6 }], nodes = new Map(data.map(o => [o.id, o])), parents = data.reduce((m, { id, parentId }) => m.set(parentId, [... (m.get(parentId) || []), id]), new Map); console.log(getAncestors(1));
.as-console-wrapper { max-height: 100% !important; top: 0; }
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.