Group By and Sum using Underscore/Lodash

后端 未结 6 2040
鱼传尺愫
鱼传尺愫 2020-12-09 04:44

I have JSON like this:

[
  {
     platformId: 1,
     payout: 15,
     numOfPeople: 4
  },
  {
     platformId: 1,
     payout: 12,
     numOfPeople: 3

  }         


        
相关标签:
6条回答
  • 2020-12-09 05:24

    You can do this without Underscore:

    var result = data.reduce(function(acc, x) {
      var id = acc[x.platformId]
      if (id) {
        id.payout += x.payout
        id.numOfPeople += x.numOfPeople
      } else {
        acc[x.platformId] = x
        delete x.platformId
      }
      return acc
    },{})
    

    But why would you want an object with numeric keys? You could convert it back to a collection:

    var toCollection = function(obj) {
      return Object.keys(obj)
        .sort(function(x, y){return +x - +y})
        .map(function(k){return obj[k]})
    }
    
    toCollection(result)
    

    Note that objects are mutated, so you may to clone them first if you want to maintain the original data.

    0 讨论(0)
  • 2020-12-09 05:24
    //Input 
    [{
      "platformId": 1,
      "payout": 15,
      "numOfPeople": 4
    }, {
      "platformId": 1,
      "payout": 12,
      "numOfPeople": 3
    }, {
      "platformId": 2,
      "payout": 6,
      "numOfPeople": 5
    }, {
      "platformId": 2,
      "payout": 10,
      "numOfPeople": 1
    }]
    
    
    //Output
    {
     "1": {
        "payout": 43,
        "numOfPeople": 13
     },
     "2": {
        "payout": 43,
        "numOfPeople": 13
     }
    }
    
    
    // Code
    output = _.reduce(input, function(acc, val, key) {
      acc[val.platformId] = {
         payout: _.sum(a, 'payout'),
         numOfPeople: _.sum(a, 'numOfPeople')
       };
      return acc;
      }, {});
    
    0 讨论(0)
  • 2020-12-09 05:27

    A (in my opinion) nice functional way using underscore.js:

    var sum = function(t, n) { return t + n; };
    _.mapObject(
        _.groupBy(data, 'platformId'),
        function(values, platformId) {
            return {
                payout: _.reduce(_.pluck(values, 'payout'), sum, 0),
                numOfPeople: _.reduce(_.pluck(values, 'numOfPeople'), sum, 0)
            };
        }
    );
    
    0 讨论(0)
  • 2020-12-09 05:32

    In the spirit of lodash one liners

    _.map(_.groupBy(your_list, 'group_by'), (o,idx) => { return { id: idx, summed: _.sumBy(o,'sum_me') }})
    
    0 讨论(0)
  • 2020-12-09 05:38

    Here's a Lodash solution to this kind of problem. It's similar to Underscore, but with some more advanced features.

    const data = [{
        platformId: 1,
        payout: 15,
        numOfPeople: 4
      },
      {
        platformId: 1,
        payout: 12,
        numOfPeople: 3
    
      },
      {
        platformId: 2,
        payout: 6,
        numOfPeople: 5
    
      },
      {
        platformId: 2,
        payout: 10,
        numOfPeople: 1
      },
    ];
    
    const ans = _(data)
      .groupBy('platformId')
      .map((platform, id) => ({
        platformId: id,
        payout: _.sumBy(platform, 'payout'),
        numOfPeople: _.sumBy(platform, 'numOfPeople')
      }))
      .value()
    
    console.log(ans);
    <script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>

    0 讨论(0)
  • 2020-12-09 05:42

    I tried to do this in the functional way, and the result was like this

    console.log(_.chain(data)
        .groupBy("platformId")
        .map(function(value, key) {
            return [key, _.reduce(value, function(result, currentObject) {
                return {
                    payout: result.payout + currentObject.payout,
                    numOfPeople: result.numOfPeople + currentObject.numOfPeople
                }
            }, {
                payout: 0,
                numOfPeople: 0
            })];
        })
        .object()
        .value());
    
    0 讨论(0)
提交回复
热议问题