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

underscore.js flatten object structure with key-value pair array of children

给定以下数据结构:

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 }
    ]
}];

...其中 children 是一个动态列表,我 "flatten" 这个结构使用几个 _.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/

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

_.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'))
    );
});

我想到的另一个解决方案:

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

http://jsfiddle.net/qk2Lu0hu/