如何反向遍历树结构
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);
我将 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);