2014-10-20 73 views
1

我有一棵樹/穿越的對象,看起來像這樣:With Underscore,我如何遞歸地壓扁一組對象?

   var data = {children: [ 
       { 
       name: 'foo', 
       url: 'http://foo', 
       children: [ 
        { 
        name: 'bar', 
        url: 'http://bar', 
        children: [] 
       } 
       ] 
      }, 
      { 
       name: 'baz', 
       url: 'http://baz', 
       children: [] 
      }, 
      { 
       name: 'biff', 
       children: [] 
      } 
      ]}; 

我需要做的就是能夠將數據壓扁成一個單一的維列表什麼:

var flattenedData = [{name: 'foo', url: 'http://foo'}, {name: 'bar', url: 'http://bar'}, {name: 'baz', url: 'http://baz'}, {name: 'biff'}]; 

目前,我我創建了一個遞歸輔助函數來遍歷數據結構並將結果推送到數組上。如果可能的話,我希望在功能上做得更好。像這樣的:

var flattenedData = _.chain(data.children).flatten().filter(function(item){//real filtering; return item;}).value(); 

問題是,展平似乎並不平坦的對象數組,只是簡單的數組。我可能是錯的。

我該如何以更有效的方式執行此任務,而無需在幫助函數中遍歷樹?

+0

更簡單的寫5行遞歸代碼。 – dfsq 2014-10-20 13:40:30

回答

1

我不明白你的意思是「扁平似乎並不扁平化一個對象數組,只是簡單的數組」 - 這是怎麼回事?它絕對可以扁平任何一種陣列。無論如何,一個簡單的通液使用reduce

Object.prototype.flatten = function() { 
    if (this instanceof Array) { 
     return this.reduce(function(a, b) { 
      return a.concat(b.flatten()); 
     }, []); 
    } 

    var res = []; 

    // this is the example condition 
    if (this.url !== undefined) { 
     res.push(this); 
    } 

    return res.concat(this.children.flatten()); 
}; 

var flat_data = data.flatten(); 
print(flat_data); 

順便說一句,這將是最好更換Object與您的自定義數據類型要扁平化,讓你不要弄亂全球原型爲所有對象。

+0

我的意思是,當我從該對象傳遞頂層數組時,flatten只返回頂層。它不知道如何重生成child.children。它很好地處理其他數組的數組。只是不包含WITH數組作爲鍵之一的對象的數組。 – 2014-10-20 14:57:21

+0

@JimWharton那麼,我的代碼就是這麼做的。 – 2014-10-20 15:16:16