在 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]; });
我想在节点 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]; });