如何反向遍历树结构

How to reverse walk a tree structure

我将 XML 解析为 JSON。我想通过遍历 JSON 并在每个节点上调用 React.createElement 来构建 React 组件树。 React.createElement 的第三个参数是一个 React 子元素数组。这意味着我必须沿着树向下走到叶节点,首先创建那些 React 元素,然后沿着每个分支向上走。

树结构上的简单递归迭代非常简单。我不确定如何说 "okay, now you're at the leaf node, go back up"。有这方面的技巧吗?

示例数据:

{  
   "section":{  
      "attrs":{  
         "class":"foo",
         "data-foo":"foo"
      },
      "#name":"section",
      "children":[  
         {  
            "attrs":{  
               "class":"region-1"
            },
            "#name":"p",
            "children":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  },
                  "#name":"span"
               }
            ],
            "span":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  }
               }
            ]
         },
         {  
            "attrs":{  
               "class":"second"
            },
            "#name":"div"
         }
      ],
      "p":[  
         {  
            "attrs":{  
               "class":"region-1"
            },
            "children":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  },
                  "#name":"span"
               }
            ],
            "span":[  
               {  
                  "attrs":{  
                     "data-children":"true"
                  }
               }
            ]
         }
      ],
      "div":[  
         {  
            "attrs":{  
               "class":"second"
            }
         }
      ]
   }
}

一般情况下,你可以使用这个算法。为了清楚起见,我使用了其他数据。您的 application-specific 代码代替了 console.log 语句。为了稳健性,我添加了一个 children 属性 是否存在的测试,并更改了数据以对其进行测试。

var data = {
    name: 'Parent',
    children: [{
            name: 'Child 1',
            children: [{
                    name: 'Child 1a',
                    children: []
                }, {
                    name: 'Child 1b'
                }
            ]
        }, {
            name: 'Child 2',
            children: [{
                    name: 'Child 2a',
                    children: []
                }, {
                    name: 'Child 2b',
                    children: []
                }
            ]
        }
    ]
};

walk(data);

function walk(node) {
    if (node.children !== undefined) {
        node.children.forEach(function(child) {
            walk(child);
        });
    }

    console.log(node.name);
}

你已经解决了一半的问题,因为你知道你应该使用递归来遍历树。但是不要一到达节点就渲染它,而是只在递归堆栈的末尾或处理完所有子节点后才渲染它。这有点像二叉树的中序遍历。

function iterate(node) {
   if (node.children) {
      node.children.forEach(function (child) {
         iterate(child);
      });
   }

   console.log(node);
}

iterate(section);