2014-10-20 42 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