我有一个像这样的对象结构;
{
this.parent = undefined;
this.children = [];
}
children
中的所有值都具有与上述相同的结构,只是它们的parent
将引用将其作为子项的对象。
如何轻松地迭代所有孩子的孩子等,但是在孩子的对象环境中呢?
我知道如何为一个物体循环孩子
obj.children.forEach(function(child) {
});
但是,如果孩子们可以进入10-20-30深的heirachy,我怎么能迭代所有孩子的孩子?
答案 0 :(得分:5)
使用recursion。
function deepForEach(node, fn) {
fn(node);
node.children.forEach(function(child) {
deepForEach(child, fn);
});
}
deepForEach(obj, function(obj) {
console.log(obj);
});
如果我们用简单的英语陈述它,它的工作方式就变得很明显了:
这种类型的递归称为preorder traversal。
答案 1 :(得分:1)
我们将编写一个递归函数。 递归表示它会再次执行:
function iterate(obj) {
// we will write the parent and the name
console.log(obj.parent + ' | ' + obj.name);
// if it has children
if (obj.children.length) {
// for each child
for (var i = 0, l = obj.children.length; i < l; i++) {
// we will call this function again
arguments.callee(obj.children[i]);
}
}
}
现在,如果我们有这样的对象:
var obj = {
name: 'P1',
parent: undefined,
children: [
{
name: 'P2',
parent: 'P1',
children: []
},
{
name: 'P3',
parent: 'P1',
children: [
{
name: 'P4',
parent: 'P3',
children: [
{
name: 'P5',
parent: 'P4',
children: []
}
]
}
]
},
{
name: 'P6',
parent: 'P1',
children: []
}
]
};
我们可以遍历它:
iterate(obj);
FIDDLE DEMO (在浏览器中打开您的控制台)
答案 2 :(得分:1)
标准方法是使用icktoofay建议的递归。
在这种处理中更烦人的是如何在“块”中管理遍历(例如,如果你想在javascript程序中使用计时器在“后台”中执行此操作)。
在这种情况下,您可以使用显式堆栈:
function process_tree(root_node,
process_node,
chunk_size,
completion_call)
{
var todo = []; // nodes that need processing
function processOneChunk() {
for (var j=0; todo.length && j<chunk_size; j++) {
var x = todo.pop();
process_node(x);
for (var i=0; i<x.children.length; i++) {
todo.push(x.children[i]);
}
}
if (todo.length) {
setTimeout(processOneChunk, 0);
} else {
completion_call();
}
}
todo.push(root_node);
setTimeout(processOneChunk, 0);
}