将键和sum值上的对象数组减少到数组中

Jes*_*sse 5 arrays json underscore.js lodash

我有以下对象:

data = [
  { name: 'foo', type: 'fizz', val: 9 },
  { name: 'foo', type: 'buzz', val: 3 },
  { name: 'bar', type: 'fizz', val: 4 },
  { name: 'bar', type: 'buzz', val: 7 },
];
Run Code Online (Sandbox Code Playgroud)

并使用了lodash地图:

result = _.map(data, function item, idx){
  return {
    key: item[key],
    values: item.value,
  }
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

[
  { key: foo, val: 9 },
  { key: foo, val: 3 },
  { key: bar, val: 4 },
  { key: bar, val: 7 },
]
Run Code Online (Sandbox Code Playgroud)

但现在我想回来:

[
  { key: 'foo', val: 12 },
  { key: 'bar', val: 11 },
]
Run Code Online (Sandbox Code Playgroud)

我尝试使用reduce,它似乎只输出到一个对象,然后我可以转换回一个数组,但我觉得必须有一个优雅的方法来使用lodash从我的源数据直接转到我想要的结果而不是所有中间步骤.

我认为是解决我的确切问题,但仅仅需要将对象转换为上面概述的所需对象数组似乎相当多.

干杯.

Gru*_*nny 6

对使用groupBy而不是reduce进行初始分组的已接受答案的扭曲:

var result = _.chain(data)
    .groupBy('name')
    .map((group, key) => ({ key, val : _.sumBy(group, 'val') }))
    .value();
Run Code Online (Sandbox Code Playgroud)


Elw*_*ens 5

有趣的是不是直截了当,因为想要通过键来累积值,但又想要键作为属性键的值。所以有点像逆映射减少:

var result = 
    _.chain(data)
        .reduce(function(memo, obj) {
            if(typeof memo[obj.name] === 'undefined') {
                memo[obj.name] = 0;
            } 
            memo[obj.name] += obj.val;
            return memo;
        }, {})
        .map(function (val, key) {
            return {key: key, val: val};
        })
        .value();
Run Code Online (Sandbox Code Playgroud)

在 es6 中为简洁起见:

_.chain(data)
    .reduce((memo, obj) => {
        memo[obj.name = obj.val] += obj.val;
        return memo; 
    }, {})
    .map((val, key) => ({key, val}))   
    .value();
Run Code Online (Sandbox Code Playgroud)