简体   繁体   中英

How to generate a flat array of ancestors from a flat normalized array of objects?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM