Reputation: 5987
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?
Upvotes: 1
Views: 6858
Reputation: 43718
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;
Upvotes: 3
Reputation: 426
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);
Upvotes: 0