如何在 lodash 中对数据进行分组和使用可选属性?

how to group data and using optional attribute in lodash?

我正在使用 lodash 进行数据操作,但当我需要对数据进行分组并使用可选属性聚合数据时,我遇到了困难。

我有以下数据,我希望通过这些数据输出以下数据:

var data = [{product: 'Matcha Latte', year: '2015', score:'43.3'},{product: 'Milk Tea', year: '2015', score:'22'},
    {product: 'Milk Tea', year: '2015', score:'33.1'},{product: 'Milk Tea', year: '2015', score:'28'},
    {product: 'Cheese Cocoa', year: '2015', score:'86.4'},{product: 'Walnut Brownie', year: '2015', score:'72.4'},
    {product: 'Matcha Latte', year: '2016', score:'40'},{product: 'Matcha Latte', year: '2016', score:'45.8'},
    {product: 'Matcha Latte', year: '2017', score:'33.3'},{product: 'Matcha Latte', year: '2017', score:'43.3'},
    {product: 'Matcha Latte', year: '2017', score:'16.73'},{product: 'Milk Tea', year: '2016', score:'73.4'},
    {product: 'Milk Tea', year: '2017', score:'50'},{product: 'Milk Tea', year: '2017', score:'.1'},
    {product: 'Walnut Brownie', year: '2016', score:'50.4'},{product: 'Walnut Brownie', year: '2016', score:'3.6'},
    {product: 'Cheese Cocoa', year: '2016', score:'65.2'},{product: 'Cheese Cocoa', year: '2017', score:'82.5'},
    {product: 'Walnut Brownie', year: '2017', score:'39.1'}];

以及预期输出:

[{product: 'Matcha Latte', '2015': 43.3, '2016': 85.8, '2017': 93.7},
        {product: 'Milk Tea', '2015': 83.1, '2016': 73.4, '2017': 55.1},
        {product: 'Cheese Cocoa', '2015': 86.4, '2016': 65.2, '2017': 82.5},
        {product: 'Walnut Brownie', '2015': 72.4, '2016': 53.9, '2017': 39.1}]

我试过以下但如何继续:

 var ans = _(data)
.groupBy('product')
.value();

使用纯 javascript 你可以减少它:

var data = [{product: 'Matcha Latte', year: '2015', score:'43.3'},{product: 'Milk Tea', year: '2015', score:'22'}, {product: 'Milk Tea', year: '2015', score:'33.1', mat:50},{product: 'Milk Tea', year: '2015', score:'28', mat:50}, {product: 'Cheese Cocoa', year: '2015', score:'86.4'},{product: 'Walnut Brownie', year: '2015', score:'72.4'}, {product: 'Matcha Latte', year: '2016', score:'40'},{product: 'Matcha Latte', year: '2016', score:'45.8'}, {product: 'Matcha Latte', year: '2017', score:'33.3'},{product: 'Matcha Latte', year: '2017', score:'43.3'}, {product: 'Matcha Latte', year: '2017', score:'16.73'},{product: 'Milk Tea', year: '2016', score:'73.4'}, {product: 'Milk Tea', year: '2017', score:'50'},{product: 'Milk Tea', year: '2017', score:'.1'}, {product: 'Walnut Brownie', year: '2016', score:'50.4'},{product: 'Walnut Brownie', year: '2016', score:'3.6'}, {product: 'Cheese Cocoa', year: '2016', score:'65.2'},{product: 'Cheese Cocoa', year: '2017', score:'82.5'}, {product: 'Walnut Brownie', year: '2017', score:'39.1'}];

var result = Object.values(data.reduce((acc, {product, year, score, mat})=>{
   acc[product] =  acc[product] || {product};
   acc[product][year] = (acc[product][year] || 0) + Number(score);
   if(mat) acc[product][`${year}_mat`] = (acc[product][`${year}_mat`] || 0) + mat;
   return acc;
},{}));

console.log(result);

将数据格式化为具有年份键和值的对象。按 product 分组,然后映射并合并每个组。如果第一个值 (a) 是数字,则合并时,将其与第二个值 (b) 合并。如果不是 return undefined,那么将使用 _.mergeWith() 使用的标准合并算法。

const data = [{"product":"Matcha Latte","year":"2015","score":"43.3"},{"product":"Milk Tea","year":"2015","score":"22"},{"product":"Milk Tea","year":"2015","score":"33.1"},{"product":"Milk Tea","year":"2015","score":"28"},{"product":"Cheese Cocoa","year":"2015","score":"86.4"},{"product":"Walnut Brownie","year":"2015","score":"72.4"},{"product":"Matcha Latte","year":"2016","score":"40"},{"product":"Matcha Latte","year":"2016","score":"45.8"},{"product":"Matcha Latte","year":"2017","score":"33.3"},{"product":"Matcha Latte","year":"2017","score":"43.3"},{"product":"Matcha Latte","year":"2017","score":"16.73"},{"product":"Milk Tea","year":"2016","score":"73.4"},{"product":"Milk Tea","year":"2017","score":"50"},{"product":"Milk Tea","year":"2017","score":".1"},{"product":"Walnut Brownie","year":"2016","score":"50.4"},{"product":"Walnut Brownie","year":"2016","score":"3.6"},{"product":"Cheese Cocoa","year":"2016","score":"65.2"},{"product":"Cheese Cocoa","year":"2017","score":"82.5"},{"product":"Walnut Brownie","year":"2017","score":"39.1"}];
    
const result = _(data)
  .map(({ year, score, ...rest }) => ({ ...rest, [year]: +score })) // create objects with the year as the key, and score as the value
  .groupBy('product')
  .map(g => _.mergeWith({}, ...g, (a, b) => _.isNumber(a) ? a + b : undefined)) // merge and sum up the score of each year, if it appears more than once
  .value();
  
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>