首页 > 解决方案 > 如何从平面标准化的对象数组中生成平面的祖先数组?

问题描述

我需要生成一个平面对象数组,其中包含一个平面标准化对象数组中给定对象的所有祖先。

存在很多将其转换为嵌套树状结构的示例,但我无法找到任何信息来简单地返回平面数组中的所有祖先。平面标准化数组中的每个对象都有一个 id 和一个 parentId。

给定一个平面标准化的对象数组

[
  {
    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,
  },
]

这样做getAncestors(1)时应该返回节点 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,
  },
]

我尝试修改函数以将其变成嵌套树状结构,但没有运气。

标签: javascript

解决方案


为了更快地访问,您需要一个Map包含所有节点及其idas 键的 a,以及一个带有parentIdas 键的所有父节点的映射。然后你需要这个函数getAncestors,在里面,你需要一个函数来获得点头和它的祖先。

将所有与归约结合并返回结果。

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; }


推荐阅读