lodash,团体和计数

时间:2014-04-12 00:25:23

标签: javascript underscore.js lodash

对于像这样的数组

[{ dep: 'A', qt: 10, price: 5},
 { dep: 'A', qt: 5,  price: 2.30 },
 { dep: 'B', qt: 3,  price: 2.20 },
 { dep: 'C', qt: 1,  price: 4 },
 { dep: 'C', qt: 4,  price: 10 }
 ...etc.. 
]

分组和求和值的优雅方式是什么,导致:

[{ dep: 'A', qt: 15, price: 61.5 },
 { dep: 'B', qt: 3, price: 2.20 },
 { dep: 'C', qt: 5: price: 44 }
]

3 个答案:

答案 0 :(得分:7)

你可以这样做:

function sumInvoices(p, c) {
    return _.extend(p, {qt:p.qt + c.qt, price:p.price + c.qt*c.price});
};

var b = _(a)
  .groupBy('dep')
  .map(function(b) {return b.reduce(sumInvoices, {dep:b[0].dep, qt:0, price:0})})
  .valueOf();

答案 1 :(得分:1)

我可能会直接转到Array.prototype.reduce这样的事情:

var b = a.reduce(function(cache, e) {
    var sum = cache.by_dep[e.dep];
    if(!sum) {
        sum = cache.by_dep[e.dep]
            = { dep: e.dep, qt: 0, price: 0 };
        cache.a.push(sum);
    }
    sum.qt    += e.qt;
    sum.price += e.price;
    return cache;
}, { by_dep: { }, a: [ ] }).a;

您想通过dep轻松访问,以便按depby_dep: { })索引运行总计,但最后还需要一个数组,以便在数组中存储相同的引用( a: [ ])。然后在最后拉出a缓存,你就完成了。

演示:http://jsfiddle.net/ambiguous/T8jgx/

这可能就像Underscore / Lodash调用的管道一样简单。但是,如果您必须使用这些库,那么您可以_(a).reduce(...)而不是a.reduce(...)

答案 2 :(得分:0)

2021 年的答案

您可以通过这种方式使用具有最高性能 O(n) 时间复杂度的 Array#reduce

const arr = [{ dep: 'A', qt: 10, price: 5},{ dep: 'A', qt: 5,  price: 2.30 },{ dep: 'B', qt: 3,  price: 2.20 },{ dep: 'C', qt: 1,  price: 4 },{ dep: 'C', qt: 4,  price: 10 }];
 
const result = arr.reduce((acc, {dep, qt, price}) => {
  acc[dep] ??= {dep, qt: 0, price: 0};
  
  acc[dep]["qt"]+= qt;
  acc[dep]["price"]+= (price * qt);
  return acc;
}, {});

console.log(Object.values(result));