【问题标题】:how to group data and using optional attribute in lodash?如何在 lodash 中对数据进行分组并使用可选属性?
【发布时间】:2020-06-03 12:07:33
【问题描述】:

我正在使用 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 underscore.js lodash


    【解决方案1】:

    使用纯 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);

    【讨论】:

    • 感谢@gorak 的回复。如果我的数据包含 [{"product":"Matcha Latte","year":"2015","score":"43.3", "mat": 40},{"product":" Matcha Latte","year":"2015","score":"22", "mat": 30}] 我想要 [{product: 'Matcha Latte', '2015_score': 75.3, '2015_mat': 70 }]
    • @Mayur,你可以用类似的逻辑来做,我用score实现了
    • @Mayur 根据您的数据,我已经更新了我的答案。看看
    【解决方案2】:

    将数据格式化为具有年份键和值的对象。按product 分组,然后映射并合并每个组。如果第一个值 (a) 是数字,则合并时,将其与第二个值 (b) 合并。如果不返回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>

    【讨论】:

    • 感谢@Ori Drori 的回复。如果我的数据包含 [{"product":"Matcha Latte","year":"2015","score":"43.3", "mat": 40},{"product":" Matcha Latte","year":"2015","score":"22", "mat": 30}] 我想要 [{product: 'Matcha Latte', '2015_score': 75.3, '2015_mat': 70 }]
    • 在这个阶段,你可以生成任何你想要的密钥,而不是[year]。像这样的东西应该可以工作:.map(({ year, score, mat, ...rest }) => ({ ...rest, [${year}_${_.isUndefined(mat) ? “分数”:“垫子”}]: +score }))。您可能希望将字符串键生成提取到函数中以使其更具可读性。
    猜你喜欢
    • 1970-01-01
    • 2018-08-28
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 2016-12-31
    • 2020-10-21
    • 2019-08-31
    • 2016-04-05
    相关资源
    最近更新 更多