【问题标题】:lodash, group and countlodash,分组和计数
【发布时间】:2014-04-12 00:25:23
【问题描述】:

对于这样的数组

[{ 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 }
]

【问题讨论】:

    标签: javascript underscore.js lodash


    【解决方案1】:

    你可以这样做:

    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();
    

    【讨论】:

      【解决方案2】:

      我可能会直接去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(...)

      【讨论】:

      • 虽然不太优雅...我希望使用 _.countBy 或 _.groupBy 得到一些东西
      • 优雅在情人眼中。我看不出一些棘手的下划线调用链如何被认为是优雅的。从 _(a).groupBy('dep') 开始,然后总结结果对象的值,如果这对您来说很优雅。
      • 下划线的跨浏览器兼容性也可能值得注意。
      【解决方案3】:

      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));

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-22
        • 1970-01-01
        • 2021-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多