Javascript lodash、组和计数

Javascript lodash、组和计数,javascript,underscore.js,lodash,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: '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 }
]

我可能会直接去做这样的事情:

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;
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();
您希望通过
dep
轻松访问,因此您可以通过
dep
by_dep:{}
)索引您的运行总数,但您也希望在末尾有一个数组,因此将相同的引用存储在一个数组中(
a:[]
)。然后拉出末尾的
a
缓存,就完成了

演示:


这可能和下划线/Lodash调用管道一样简单。但是如果您必须使用这些库,那么您可以
\uuuA.reduce(…)
而不是
a.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;
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();
2021年的答案 您可以通过以下方式使用具有最高性能的
O(n)
时间复杂度:

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,价格:0};
acc[dep][“qt”]+=qt;
acc[dep][“价格”]+=(价格*qt);
返回acc;
}, {});

console.log(Object.values(result))虽然不太优雅。。。我希望能用u.countBy或u.groupbygrateous在旁观者眼里。我看不出一些复杂的下划线调用链如何被认为是优雅的。从a.groupBy('dep')
开始,然后将结果对象的值相加(如果您觉得这样做很优雅的话)。下划线形式的跨浏览器兼容性也可能值得注意。