2014-08-29 107 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