reactjs react中层次无限深度树结构的迭代绘制

epggiuax  于 2023-03-08  发布在  React
关注(0)|答案(1)|浏览(173)

我创建了一个层次树结构,并希望以两种方式呈现它:递归地和迭代地。这个结构可以有无限多的子结构。我已经设法递归地渲染了这个结构,但是,我似乎不能解决如何迭代地完成它。
下面是我的结构:

const nodes = [
    {
      name: "node 1",
      children: [
        {
          name: "node 1-1",
          children: [
            {
              name: "node 1-1-1",
              children: [
                {
                  name: "node 1-1-1-1",
                  children: [],
                },
                {
                  name: "node 1-1-1-2",
                  children: [],
                },
              ],
            },
            { name: "node 1-1-2", children: [] },
          ],
        },
        {
          name: "node 1-2",
          children: [],
        },
        {
          name: "node 1-3",
          children: [],
        },
      ],
    },
    {
      name: "node 2",
      children: [],
    },
  ];

我为递归解决方案编写的代码:

const getTreeRecursively = (nodes: any) =>
    nodes?.map((node: any) => {
      if (node.children?.length === 0) {
        return (
          <div
            style={{
              textAlign: "left",
              marginLeft: "15px",
            }}
          >
            <div>***{node.name}</div>
          </div>
        );
      }
      return (
        <div
          style={{
            textAlign: "left",
            marginLeft: "15px",
          }}
        >
          <div>***{node.name}</div>
          {getTreeRecursively(node.children)}
        </div>
      );
    });

  return <>{getTreeRecursively(nodes)}</>;

它看起来是这样的:
Example how structure is rendered

现在关于迭代的解决方案,我在互联网上搜索了一下,找到了一个平面数组的解决方案。但是,这个解决方案不能让我渲染结构,而只是将平面数组重新排列成我在递归解决方案中使用的相同结构。我在想,也许平面结构可以在react中以某种方式渲染。

const flat = [
    { id: 1, parentId: 3 },
    { id: 3, parentId: 8 },
    { id: 4, parentId: 6 },
    { id: 6, parentId: 3 },
    { id: 7, parentId: 6 },
    { id: 8, parentId: null },
    { id: 16, parentId: null },
    { id: 10, parentId: 8 },
    { id: 15, parentId: 8 },
    { id: 13, parentId: 14 },
    { id: 14, parentId: 10 },
  ];

  const root = [];

  flat.forEach((node: any) => {
    if (!node.parentId) {
      return root.push(node);
    }

    const parentIndex = flat.findIndex((el: any) => el.id === node.parentId);
    if (!flat[parentIndex].children) {
      return (flat[parentIndex].children = [node]);
    }

    return flat[parentIndex].children.push(node);
  });

  console.log(root);

image of the console logged root
尝试递归解决方案并成功,但无法管理以无限深度迭代呈现层次树。

6ju8rftf

6ju8rftf1#

递归方法是可行的方法:平均而言,所使用的堆栈空间是O(log𝑛)(其中𝑛是树中的节点数),并且在最坏的情况下是O(𝑛)。
通过在显式堆栈变量中维护当前节点的路径,可以使此过程迭代:

const getTreeIteratively = (nodes) => {
  const stack = [[nodes, 0, []]];
  while (stack.length > 0) {
    const [children, i, elements] = stack.at(-1);
    if (i >= children.length) {
      stack.pop();
      if (stack.length == 0) return elements;
      const up = stack.at(-1);
      up[2].push(
        <div
          style={{
            textAlign: "left",
            marginLeft: "15px",
          }}
        >
          <div>***{up[0][up[1]++].name}</div>
          {elements}
        </div>
      );
    } else {
      stack.push([children[i].children ?? [], 0, []]);
    }
  }
}

相关问题