如何使用node-js使用聚合函数

时间:2013-08-18 12:21:35

标签: javascript node.js group-by aggregate-functions

我有一个json,其数组名为chargeamountunitLevel。我想通过chargeAmountUnit进行分组来总结chargeAmount。输入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"
        }

    ]

结果可能如下:

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

        ]

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

您始终可以使用reduce功能。这里,因为我们向initialValue提供了reduce作为第二个参数,所以第一次调用callback时,该值将作为result参数传递。然后,对于所有后续呼叫,result将是前一次呼叫的返回值。

如果initialValue chargeAmountUnit已作为密钥存在,我们基本上会检查o个对象。如果没有,我们创建一个具有对象o的相同属性值的新对象,并使用initialValue作为键将其放在我们的chargeAmountUnit对象中。如果它确实存在,我们使用chargeAmountUnit作为关键字检索以前创建的对象,我们只是总结相关的值。

另外,您可能已经注意到我们正在将数据中的创建对象推送出去,这是因为最后您需要一个数组,而不是像:

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

以下是如何操作:

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;

编辑:要按多个字段进行分组,您可以按key创建一个分组,方法是按字段字符串值进行分组。

以下内容将分组在chargeAmountUnitcurrencyCode

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;

答案 1 :(得分:1)

你可以使用underscore.js

这是代码:

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);