展平分层数据

时间:2015-02-11 12:00:15

标签: javascript underscore.js

我有这样的数据结构:

{
    name: 'test',
    config: { ... },
    prev: {
        name: 'test1.1',
        config: { ... },
        prev: {
            name: 'test1.1.1',
            config: { ... },
            prev: {
                name: 'test1.1.1.1',
                config: { ... },
                prev: undefined
            }
        }
    }
}

结构可以在'prev'对象中包含任意数量的递归但相同的结构。

我想提取每个孩子的'name'属性。如何使用下划线将其展平以产生如下结果集:

['test', 'test1.1', 'test1.1.1', 'test1.1.1.1']

如果展平过程可能会返回类似

的内容,那就更好了
[
    {name: 'test', config: { ... }}, 
    {name: 'test1.1', config: { ... }}, 
    {name: 'test1.1.1', config: { ... }},
    {name: 'test1.1.1.1', config: { ... }}
]

我目前的解决方案就是这个(这不是最优的。我想用一个_.chain来制作它):

var _self = {
    flatten: function (obj) {
        var map = [];
        return _self.flattenRecurse(obj, map);
    },
    flattenRecurse: function (obj, map) {
        map.push({name: obj.name, config: obj.config});
        if (obj.prev) {
            _self.flattenRecurse(obj.prev, map);
        }
    }
}
var flattened = _self.flatten(data);

3 个答案:

答案 0 :(得分:8)

使用简单的js更容易,比如

function flatten (data) {
  var result = [];

  while (data) {
    result.push({name: data.name, config: data.config});
    data = data.prev;
  }

  return result;
}

// get full object
 flatten(data)

// get only names
var res = flatten(data).map(function (el) {
  return el.name;
});

Example

答案 1 :(得分:1)

递归策略

var data = {
    name: 'test',
    config: { },
    prev: {
        name: 'test1.1',
        config: { },
        prev: {
            name: 'test1.1.1',
            config: {  },
            prev: {
                name: 'test1.1.1.1',
                config: { },
                prev: undefined
            }
        }
    }
};

var reduced = flatten(data, function(item) {
    return { name: item.name, config: item.config };
});

print(reduced.map(function(item) { return item.name }).join(', '));
 
function flatten(data, reducerFn, result) {
    result = result || [];
    if (data === undefined) return result;
    return flatten(data.prev, reducerFn, result.concat([reducerFn(data)]));
}

/* For Display Purposes Only */function print(str) {
    document.getElementById('display').innerHTML += str + '<br />';
}
<div id="display"></div>

答案 2 :(得分:0)

对于没有递归的固定结构,可以简单地做到这一点:

var flatten = function(data){
    var result = [] 
     data.projects.forEach(p => {
        p.articles.forEach(a => {
            a.months.forEach(m => {
                result.push({project: p.name, article: a.name, month: m.month, someValue: m.someValue});
            })
        })
    })
    return result;
}
var table = flatten(tree)