简体   繁体   中英

How to use aggregate functions using node-js

I have a json which has the array called as chargeamountunitLevel. I want to sum-up the chargeAmount by grouping by the chargeAmountUnit.The Input json:

 "chargeamountunitLevel": [
        {
            "chargeAmount": 4,
            "chargeAmountUnit": "per hour",
            "currencyCode": "USD"
        },
        {
            "chargeAmount": 50,
            "chargeAmountUnit": "per hour",
            "currencyCode": "USD"
        },
        {
             "chargeAmount": 25,
             "chargeAmountUnit": "per month",
             "currencyCode": "USD"
        },
        {
             "chargeAmount": 25,
             "chargeAmountUnit": "per month",
             "currencyCode": "USD"
        }

    ]

The result might be as follows:

    "chargeamountunitLevel": [
        {
            "chargeAmount": 54,
            "chargeAmountUnit": "per hour",
            "currencyCode": "USD"
        },
        {
             "chargeAmount": 50,
             "chargeAmountUnit": "per month",
             "currencyCode": "USD"
        }

        ]

Any suggestions?

You could always make use of the reduce function. Here since we provided an initialValue as a second argument to reduce , the first time the callback will be called, that value will be passed as the result argument. Then for all subsequent calls, result will be the return value of the previous call.

Here we basically check in our initialValue object if the chargeAmountUnit of o already exists as a key. If it doesn't, we create a new object having the same property value of the object o and put it in our initialValue object using the chargeAmountUnit as key. If it does exists however, we retrieve the previously created object using chargeAmountUnit as a key and we simply sum up the concerned values.

Also, you may have noticed that we are pushing the created objects in an array, that's because at the end you want an array as a result, not something like:

{
    'per month': {...},
    'per hour': {...}
}

Here's how to do it:

data.reduce(function (result, o) {
    var unit = o.chargeAmountUnit;
    if (!(unit in result)) {
        result.arr.push(result[unit] = { 
            chargeAmountUnit: unit, 
            chargeAmount: o.chargeAmount, 
            currencyCode: o.currencyCode 
        });
    } else {
        result[unit].chargeAmount += o.chargeAmount;
    }

    return result;
}, { arr: [] }).arr;

EDIT: To group by multiple fields, you can simply create a group by key by concanating the group by field string values.

The following will group on chargeAmountUnit and currencyCode .

data.reduce(function (result, o) {
    //compute group by key
    var key = o.chargeAmountUnit + o.currencyCode;
    if (!(key in result)) {
        result.arr.push(result[key] = { 
            chargeAmountUnit: o.chargeAmountUnit, 
            chargeAmount: o.chargeAmount, 
            currencyCode: o.currencyCode 
        });
    } else {
        result[key].chargeAmount += o.chargeAmount;
    }

    return result;
}, { arr: [] }).arr;

you can use underscore.js

here is the code:

var _ = require('underscore');    // use `npm install underscore`
var util = require('util');       // nodejs default modules

var data = {
  "chargeamountunitLevel": [{
    "chargeAmount": 4,
    "chargeAmountUnit": "per hour",
    "currencyCode": "USD"
  }
  , {
    "chargeAmount": 50,
    "chargeAmountUnit": "per hour",
    "currencyCode": "USD"
  }
  , {
    "chargeAmount": 25,
    "chargeAmountUnit": "per month",
    "currencyCode": "USD"
  }
  , {
    "chargeAmount": 10,
    "chargeAmountUnit": "per month",
    "currencyCode": "USD"
  }
  , {
    "chargeAmount": 1,
    "chargeAmountUnit": "per month",
    "currencyCode": "RMB"
  }
  , {
    "chargeAmount": 25,
    "chargeAmountUnit": "per month",
    "currencyCode": "HKD"
  }]
};

// This should give you an array of objects that
// are grouped by chargeAmountUnit.
var tmp = _.groupBy(data["chargeamountunitLevel"], function(d){ 
  return d["chargeAmountUnit"]; 
});
// Show the temporary result :o)
console.log(tmp);

// Now group the result with currency code
var tmp2 = {};
_.each(tmp, function(t, unit){
  tmp2[unit] = _.groupBy(t, function(d){
    return d["currencyCode"];
  });
});

// show the temp result again
console.log("tmp2: \n" +  util.inspect(tmp2, false, null, true));   // util.inspect() is different in node v0.10.x

var finalResult = [];
_.each(tmp2, function(t, unit){
  _.each(t, function(items, currency){
    var total = 0;
    _.each(items, function(item){
      total += item["chargeAmount"];     // should also * currencyCode?
    });
    finalResult.push({
      "chargeAmountUnit" : unit
      , "chargeAmount" : total
      , "currencyCode" : currency    // Update it yourself :o)
    });
  });
});

console.log(finalResult);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM