2014-08-29 111 views
-4

假设这样的结构:这个扁平化的递归版本?

[ 
{name: 'a', children: [{name: 'c', children: [...]}]}, 
{name: 'b', children: [{name: 'd', children: [...]}]} 
] 

那去说N级深。

什么将递归的方式来获取平面数组中的所有元素?

[{name: a}, {name: b}, ...] 

请注意,家长可能有多个子女。

回答

1

你可以做这样的事情;

function recursivelyAdd(el, array) { 
    array.push(el); 

    for (var i=0; i< el.children.length; i++) { 
     recursivelyAdd(el.children[i], array); 
    } 

    delete el.children; 
} 

...请注意,它修改了现有的对象,删除了“children”属性,一旦处理完毕。删除delete el.children行,如果你不想这样... ...

像这样使用它;

var ar = []; 

recursivelyAdd(rootPerson, ar); 

// ar will now be all the people! 
+0

谢谢!我一直在多次调用函数,并且认为正确的方法是在函数中传递一些额外的参数,以传递一些代表状态的数组。 – rollingBalls 2014-08-29 16:23:10

+1

@rollingBalls:使用recusion时,需要1)终止符(递归结束的方式)和2)一种方法来收集结果(通过存储每个函数返回的内容,或者传递一个“状态”提到)。在递归函数中,1.在没有孩子的情况下实现(因为我们不会再递归)。 2是通过添加到我们传递的数组来实现的。 – Matt 2014-08-29 16:31:26

+0

谢谢你的澄清马特。因此,具有状态的替代版本也是“可接受的”解决方案。我认为你的实现更简单:) – rollingBalls 2014-08-29 16:42:21

1
var struc = [ 
{name: 'a', children: [{name: 'c', children: []}]}, 
{name: 'b', children: [{name: 'd', children: []}]} 
]; 

function getNames(children) { 
    return children.reduce(function(names, child) { 
    return names.concat(child.name, getNames(child.children)); 
    }, []); 
}; 

getNames(struc); 
// ["a", "c", "b", "d"] 

这样的回答消除了环路和不修改原始对象。

+0

...好吧,你可以在语法上删除循环。 'reduce()'仍然会在内部执行:)。 – Matt 2014-08-29 16:33:15

+0

是的。开发人员需要考虑的更少。 – 2014-08-29 16:34:04