如何使用 lodash 对 sum 进行分组

Posted

技术标签:

【中文标题】如何使用 lodash 对 sum 进行分组【英文标题】:How to groupBy with sum using lodash 【发布时间】:2022-01-12 19:48:12 【问题描述】:

我有 productId,它是一个值数组。

const groupByvalue= [1, 2];

我的产品有多个产品数组。

const products = [
  
    id: 1,
    name: 'milk',
    qty: 2
  ,
  
    id: 2,
    name: 'butter',
    qty: 2
  ,
  
    id: 3,
    name: 'milk',
    qty: 2
  ,
  
    id: 2,
    name: 'butter',
    qty: 2
  ,
  
    id: 1,
    name: 'milk',
    qty: 2
  ,
  
    id: 3,
    name: 'butter',
    qty: 2
  ,
  
    id: 1,
    name: 'milk',
    qty: 2
  ,
  
    id: 3,
    name: 'butter',
    qty: 2
  
];

const groupByKey = 'id';

我需要根据产品的 id 对产品进行分组。

conditions

i)groupBy 应该基于 groupByvaluegroupBykey 数组(仅 groupBy 1、2) ii)在组之后,它应该总结所有的数量

预期

[
  
    id: 1,
    name : "milk", 
    qty : sum of all qty
  ,
  
    id: 2,
    name : "butter", 
    qty : sum of all qty
  
];

谢谢!!

【问题讨论】:

【参考方案1】:

使用 Lodash

var _ = require('lodash');

var groupByValue = [1, 2];
var groupByKey   = 'id';

const products = [
     id: 1, name: 'milk', qty: 2 ,
     id: 2, name: 'butter', qty: 2 ,
     id: 3, name: 'milk', qty: 2 ,
     id: 2, name: 'butter', qty: 2 ,
     id: 1, name: 'milk', qty: 2 ,
     id: 3, name: 'butter', qty: 2 ,
     id: 1, name: 'milk', qty: 2 ,
     id: 3, name: 'butter', qty: 2 
]
           
const ans = _(products)
  .groupBy(groupByKey)
  .map((product) => 
        if(groupByValue.includes(product[0].id))
            return 
                id: product[0].id,
                name: product[0].name,
                qty: _.sumBy(product, 'qty')
            
        
    )
  .value()

console.log(ans.filter(item => item));

输出:-

[  id: 1, name: 'milk', qty: 6 ,  id: 2, name: 'butter', qty: 4  ]

【讨论】:

【参考方案2】:

不需要任何 lodash,这是一个原生的 .reduce() 任务。你可能会喜欢;

var groupByValue = [1, 2],
    groupByKey   = 'id',
    products     = [  id  : 1
                     , name: 'milk'
                     , qty : 2
                     
                   ,  id  : 2
                     , name: 'butter'
                     , qty : 2
                     
                   ,  id  : 3
                     , name: 'milk'
                     , qty: 2
                     
                   ,  id  : 2
                     , name: 'butter'
                     , qty : 2
                     
                   ,  id  : 1
                     , name: 'milk'
                     , qty : 2
                     
                   ,  id  : 3
                     , name: 'butter'
                     , qty : 2
                     
                   ,  id  : 1
                     , name: 'milk'
                     , qty : 2
                     
                   ,  id  : 3
                     , name: 'butter'
                     , qty : 2
                     
                   ],
  interim        = products.reduce( (r,p) => ( groupByValue.includes(p[groupByKey]) && (r[p[groupByKey]] ? r[p[groupByKey]].qty += p.qty
                                                                                                         : r[p[groupByKey]] = Object.assign(,p))
                                             , r
                                             )
                                  , 
                                  ),
  result         = Object.values(interim);
  console.log(result);

带有id:3milk 产品不计算在内。

【讨论】:

【参考方案3】:

我会先过滤数组,然后制作地图, 这可以在单个 .reduce(...) 函数中完成,但使用 lodash 更具可读性:

const _ = require('lodash');
const groupByValue = [1, 2];
const groupByKey = 'id';

 const products = [
     id: 1, name: 'milk',  qty:  1 ,
     id: 2, name: 'butter', qty: 2 ,
     id: 3, name: 'cheese',  qty: 4 ,
     id: 2, name: 'butter', qty: 5 ,
     id: 1, name: 'milk',  qty: 3 ,
     id: 3, name: 'cheese', qty: 6 ,
     id: 1, name: 'milk',  qty: 1 ,
     id: 3, name: 'cheese', qty: 7 
];

const result = _(products)
       .filter(itm => groupByValue.includes(itm.id))
       .groupBy(groupByKey)
       .map(arr => 
           const  id, name  = arr[0];

           return  id, name, qty: _(arr).sumBy('qty') ;
       )
       .value();

console.log(result);

// output: [ id: 1, name: 'milk', qty: 5,id: 2, name: 'butter', qty: 7]

【讨论】:

以上是关于如何使用 lodash 对 sum 进行分组的主要内容,如果未能解决你的问题,请参考以下文章

使用 lodash 或 ES5 对对象进行分组

如何按键对一组对象进行分组?

如何按键对一组对象进行分组?

如何使用 lodash 按嵌套属性分组?

如何对一组对象进行分组并将其映射到不同的结构?

如何使用 Lodash.js 对集合/数组进行反透视?