我有一个像这样的数据集:
var ds = [
{time: "t1", parameter_q: "value1"},
{time: "t2", parameter_q: "value2"},
{time: "t3", parameter_q: "value3"},
....
];
数据集包含小时值,日期/时间格式为dd / mm / yyyy hh:mm:ss
我正在寻找一种使用老式JavaScript计算值的每日平均值(属性parameter_q)的方法。
我从这样的功能开始:
function calcDAvg(ds) {
for (var i = 0; i < ds.length ; i++){
ds[i].uday = (ds[i].xtime.getMonth() + 1) + "/" + ds[i].xtime.getDate() + "/" + ds[i].xtime.getFullYear();
};
var dailyaverage = [];
var avgqarray = [];
var hourAry = [];
var checkday = undefined;
//defining temporal array
var tmpAry = [];
var hours = 0;
for (var i = 0; i < ds.length ; i++) {
var tmpObj = new Object();
var iday = ds[i].uday;
if (iday != checkday ) {
avgqarray.push(foo); //foo: function to calculate the average of tmpAry
tmpObj.xtime = new Date(iday);
dailyaverage.push(tmpObj);
tmpAry = [];
checkday = iday;
tmpAry.push(ds[i].parameter_q);
hourAry.push(hours);
hours = 1;
} else {
tmpAry.push(ds[i].parameter_q);
hours++;
}
}
return dailyaverage;
}
我注意到数据集中的最后一个时间步被忽略了,这不是我所期望的。否则,我无法相信这是在JavaScript中计算数据集每日平均值的最优雅方法。有没有更优雅的方式?
感谢您的帮助。
答案 0 :(得分:1)
鉴于日期格式为dd / mm / yyyy hh:mm:ss,您可以按日期部分进行分组,然后计算平均值,例如
var ds = [
{time: "01/06/2018 10:00:00", parameter_q: "25"},
{time: "01/06/2018 11:00:00", parameter_q: "30"},
{time: "01/06/2018 12:00:00", parameter_q: "35"},
{time: "02/06/2018 10:00:00", parameter_q: "28"},
{time: "02/06/2018 11:00:00", parameter_q: "38"},
{time: "02/06/2018 12:00:00", parameter_q: "48"}
];
function getAverages(data) {
var sums = data.reduce(function(acc, obj) {
var date = obj.time.split(' ')[0];
if (!acc[date]) {
acc[date] = {sum:0, count:0};
}
acc[date].sum += +obj.parameter_q;
acc[date].count++;
return acc;
}, Object.create(null));
return Object.keys(sums).map(function(date) {
return {[date]:sums[date].sum/sums[date].count};
});
}
console.log(getAverages(ds));
您可以使用 forEach 做很多相同的事情。不要试图将日期字符串转换为日期,我认为没有必要。
答案 1 :(得分:0)
像这样循环遍历数据时,在循环完成后处理缓冲区中剩余的任何数据始终很重要。这可能是导致您出错的原因。
下面是尝试执行一些更简洁的代码的尝试。它利用reduce函数创建每个日期的平均值字典。尽管这种方法的性能可能会稍有下降,但它不需要数据按时间顺序排列。
function calcDAvg(ds) {
var groups = ds.reduce(function(acc,cur) {
var key = (cur.xtime.getMonth() + 1) + "/" + cur.xtime.getDate() + "/" + cur.xtime.getFullYear();
if (acc[key]) {
acc[key].sum += cur.parameter_q;
acc[key].count++;
} else {
acc[key] = { sum: cur.parameter_q, count: 1 };
}
}, {});
var dailyAverage = [];
for (var key in groups)
{
dailyAverage.push(groups[key].sum / groups[key].count);
}
return dailyAverage;
}