如何逆走树形结构

How to reverse walk a tree structure

本文关键字:结构 何逆走      更新时间:2023-09-26

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

简单,在树结构上进行递归迭代已经足够简单了。我不知道怎么说"好了,现在你在叶节点,回到上面去"有什么技巧吗?

样本数据:

{  
   "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"
            }
         }
      ]
   }
}

一般情况下,可以使用此算法。为了清晰起见,我使用了其他数据。特定于应用程序的代码将取代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);