在 javascript 集合中分组(按年)和总和

Group (by year) and sum in javascript collection

我想在节点 javascript 应用程序中将同一年的值汇总为每年的单个值。我想避免 for(;;) 迭代,发现年份,对值求和....
也许 Underscore 库中有一些东西(比如 _.groupBy 但我不知道如何使用在这种情况下)。
json数据是这样的(即季度收入数据):

{ "data":
 ["2015-07-22",125677000000.0],
 ["2015-04-28",129006000000.0],
 ["2015-01-28",123328000000.0],
 ["2014-10-27",111547000000.0],
 ["2014-07-23",120940000000.0],
 ["2014-04-24",120178999999.99998],
 ["2014-01-28",129684000000.0],
 ["2013-10-30",123549000000.0],
 ["2013-07-24",123354000000.00002],
 ["2013-04-24",135490000000.0],
 ["2013-01-24",127346000000.0],
 ["2012-10-31",118210000000.0],
 [etc...]}

结果应该是:

 { "data":
 ["2015",sum of all 2015 data],
 ["2014",sum of all 2014 data],
 ["2013",sum of all 2013 data],
 [etc...]}

完全没有问题,没有循环,不需要下划线。

a = { "data":[
 ["2015-07-22",125677000000.0],
 ["2015-04-28",129006000000.0],
 ["2015-01-28",123328000000.0],
 ["2014-10-27",111547000000.0],
 ["2014-07-23",120940000000.0],
 ["2014-04-24",120178999999.99998],
 ["2014-01-28",129684000000.0],
 ["2013-10-30",123549000000.0],
 ["2013-07-24",123354000000.00002],
 ["2013-04-24",135490000000.0],
 ["2013-01-24",127346000000.0],
 ["2012-10-31",118210000000.0]]}


var years = a.data.map(function(d) {
    return [new Date(d[0]).getFullYear(), d[1]];
 });

var sums = years.reduce(function(prev, curr, idx, arr) {
    var sum = prev[curr[0]];
    prev[curr[0]] = sum ? sum + curr[1] : curr[1];
    return prev; 
 }, {});

> sums
Object {2012: 118210000000, 2013: 509739000000, 2014: 482350000000, 2015: 378011000000}

请注意,我必须修复您的 JSON 数据。您发布的那个无效 JSON,所以我只是在列表列表周围添加了数组括号。

如果你愿意,你甚至可以在一行中完成。

a.data.map(function(d) { return [new Date(d[0]).getFullYear(), d[1]]; }).reduce(function(prev, curr, idx, arr) { var sum = prev[curr[0]]; prev[curr[0]] = sum ? sum + curr[1] : curr[1]; return prev; }, {});

开玩笑,请不要那样做:)

既然你提到了下划线,迭代一次并调用索引就可以了

var json = { "data":   [["2015-07-22",125677000000.0],  ["2015-04-28",129006000000.0],  ["2015-01-28",123328000000.0],  ["2014-10-27",111547000000.0],  ["2014-07-23",120940000000.0],  ["2014-04-24",120178999999.99998],  ["2014-01-28",129684000000.0],  ["2013-10-30",123549000000.0],  ["2013-07-24",123354000000.00002],  ["2013-04-24",135490000000.0],  ["2013-01-24",127346000000.0],  ["2012-10-31",118210000000.0]]
           };

var sums = {};

_.each(json.data, function(arr) { 
    var index = arr[0].split('-')[0];
    if (typeof(sums[index]) !== 'undefined') {
        sums[index] += arr[1];
    } else {
        sums[index] = arr[1];
    } });

是的,正如@bbill 指出的那样,我也修复了你的 JSON:)

这是一个JSFiddle

var data = [
    ["2015-07-22",125677000000.0],
    ["2015-04-28",129006000000.0],
    ["2015-01-28",123328000000.0],
    ["2014-10-27",111547000000.0],
    ["2014-07-23",120940000000.0],
    ["2014-04-24",120178999999.99998],
    ["2014-01-28",129684000000.0],
    ["2013-10-30",123549000000.0],
    ["2013-07-24",123354000000.00002],
    ["2013-04-24",135490000000.0],
    ["2013-01-24",127346000000.0],
    ["2012-10-31",118210000000.0]
];

在地图中创建总和(年 -> 总和)- 然后使用 _.pairs:

将地图转换为数组
var result = _.pairs(data.reduce(function(prev, curr) {
    var year = curr[0].substr(0, 4);
    prev[year] = prev[year] ? prev[year] + curr[1] : curr[1];
    return prev;
}, {}));

然后按第一个元素降序排列:

result.sort(function(a, b) { return a[0] < a[1]; });