这是我想出来的。
它与其他答案有点不同,因为它具有预先填充 0 平均金额的完整结构。这可能很有用,因为检查没有条目的月份和日期不会返回 undefined。它还单独存储所有条目,以防万一。如果它以某种方式破坏了事物,您当然可以将其扔掉——在计算平均值之后。
好的,这里是条目:
data = [
{day: "mon", amount: "4", month: "jan"},
{day: "tue", amount: "2", month: "jan"},
{day: "wed", amount: "3", month: "jan"},
{day: "wed", amount: "1", month: "jan"}
];
然后我们构建保存平均值的 R 对象。您可以简单地手动完成此操作,但写出 84 次日期元素将非常乏味。此外,这可以很容易地更改月份和日期的名称 - 即。当您需要使用不同的语言时。
var m, M=['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'];
var d, D={'mon':0,'tue':1,'wed':2,'thu':3,'fri':4,'sat':5,'sun':6};
var R = {};
for(m=0;m<12;m++){
R[M[m]] = []; // M[0] = jan,...
for(d in D){ // d = mon,...
R[M[m]][D[d]] = {day:d,avg_amount:0,all:[]}; // D[d] = 0,...
// R = { jan:[ {day:'mon',avg_amount:0,all:[]},...
}
}
这是剩下的,遍历 data 数组,将金额存储在 R 对象中,最后在 R 中遍历每一天> 对象,计算平均值。
var sum,n;
data.map( x => R[x.month][D[x.day]].all.push(parseInt(x.amount)) );
for(m in R) for(d=0;d<7;d++){
sum = R[m][d].all.reduce((total,x)=>total+x,0);
n = R[m][d].all.length;
R[m][d].avg_amount = ((n==0)? 0 : sum/n);
// delete R[m][d].all;
// in case the structure can't have any extra fields
// we can dispose of the list of all entries belonging
// to a particular month and day
}
您还可以创建一个包含新数据的函数,如下所示:
function processData(data){
var sum,n;
data.map( x => R[x.month][D[x.day]].all.push(parseInt(x.amount)) );
for(m in R) for(d=0;d<7;d++){
sum = R[m][d].all.reduce((total,x)=>total+x,0);
n = R[m][d].all.length;
R[m][d].avg_amount = ((n==0)? 0 : sum/n);
}
}
最后,你有没有考虑更换
{"jan":["mon",avg_amount:"4"},{day:"tue", avg_amount:"2"}]}
与
{"jan":{"mon":5,"tue":3}}
因为除非这种特定的结构是强加给你的,否则像这样混合对象和数组对我来说似乎有点笨拙。它可以做得更整洁。只是一个建议。
R.jan[0].avg_value; // avg_amount of january, monday
对
R.jan.mon; // avg_amount of january, monday