javascript集合中的组(按年份)和总和

javascript集合中的组(按年份)和总和,javascript,underscore.js,Javascript,Underscore.js,我想在一个节点javascript应用程序中,将同一年的值相加为一个值。我希望避免for(;)迭代、发现年份、求和值……下划线库中可能有某些内容(如u.groupBy,但我不知道在这种情况下如何使用它)。 json数据如下(即季度收入数据): 结果应该是: { "data": ["2015",sum of all 2015 data], ["2014",sum of all 2014 data], ["2013",sum of all 2013 data], [etc...]} 这根

我想在一个节点javascript应用程序中,将同一年的值相加为一个值。我希望避免for(;)迭代、发现年份、求和值……
下划线库中可能有某些内容(如u.groupBy,但我不知道在这种情况下如何使用它)。
json数据如下(即季度收入数据):

结果应该是:

 { "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:)

这里有一个例子

在映射中创建总和(年份->总和)-然后将映射转换为具有
对的数组

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]; });
result.sort(函数(a,b){返回a[0]
想要避免使用循环的原因是什么?你无法避免循环。。如果您使用框架,那么这个框架将使用循环..感谢所有的解决方案,我会说这是我更喜欢的一个(以及我正在寻找的MapReduce)。
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]; });