underscore.js使用键值对子项数组展平对象结构

时间:2016-07-01 09:39:52

标签: javascript underscore.js lodash

鉴于以下数据结构:

var data = [{
    name: "Some Name",
    id: 1,
    children: [
        { name: "prop1", value: 1 },
        { name: "prop2", value: 2 },
        { name: "prop3", value: 3 }
    ]
},
{
    name: "Some Other Name",
    id: 2,
    children: [
        { name: "prop1", value: 4 },
        { name: "prop2", value: 5 },
        { name: "prop3", value: 6 }
    ]
}];

...其中,子项是动态列表,我使用几个_.each循环“扁平化”此结构,如下所示:

_.each(data, d => {
    _.each(d.children, c => {
        d[c.name] = c.value;
    })
});

...仅用于实现二维数据结构,如:

[{
    name: "Some Name",
    id: 1,
    prop1: 1,
    prop2: 2,
    prop3: 3
},
{
    name: "Some Other Name",
    id: 2,
    prop1: 4,
    prop2: 5,
    prop3: 6
}];

所以我希望用undercore.js可能有一种巧妙的方法来实现这个目标吗?

JSFiddle玩:http://jsfiddle.net/3m3dsv47/

2 个答案:

答案 0 :(得分:1)

我提出的另一个解决方案:

_.each(data, d => {
    _.extend(d, _.object(_.map(d.children, c => {
        return [c.name, c.value];
    })));
});

http://jsfiddle.net/qk2Lu0hu/

答案 1 :(得分:0)

此解决方案使用UnderscoreJS。与您自己的解决方案相比,这不会修改原始数据,而是创建它的副本。我不会说它更整洁"但是在这里它是:)

_.map(data, function(e){ 
    return _.defaults({name: e.name, id: e.id}, 
      _.reduce(e.children, function (acc, e) {
        acc[e.name] = e.value; return acc; 
      }, {})
    ); 
  });

如果我将此应用于您的数据我

 [
   {"name":"Some Name","Prop1":1,"Prop2":2,"Prop3":3},
   {"name":"Some Other Name","Prop1":4,"Prop2":5,"Prop3":6}
 ]

您也可以省略_.reduce。虽然它可能看起来更优雅,但由于迭代所有孩子两次(_.pluck),它的效率甚至低于第一个。

_.map(data, function(e){
    return _.defaults({id: e.id, name: e.name}, 
      _.object(_.pluck(e.children, 'name'), _.pluck(e.children, 'value'))
    );
});