对于像这样的数组
[{ 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 }
]
答案 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
轻松访问,以便按dep
(by_dep: { }
)索引运行总计,但最后还需要一个数组,以便在数组中存储相同的引用( a: [ ]
)。然后在最后拉出a
缓存,你就完成了。
演示:http://jsfiddle.net/ambiguous/T8jgx/
这可能就像Underscore / Lodash调用的管道一样简单。但是,如果您必须使用这些库,那么您可以_(a).reduce(...)
而不是a.reduce(...)
。
答案 2 :(得分:0)
您可以通过这种方式使用具有最高性能 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));