简体   繁体   中英

JS expression to calculate the average value of all given data points within a month, for all months represented in the data points

I'm looking for an JavaScript expression to calculate the average value of all given data points within a month, for all months represented in the data points. So far I've only thought to hard code new arrays for each month and add to them with 12 conditionals, then average the values of each list. But I feel like there certainly must be a cleaner more efficient way. sample data = (eg. [YYYY, MM, DD, Value] ):

[
  [ 2020, 1, 2, 1058 ],
  [ 2020, 1, 8, 1055 ],
  [ 2020, 1, 12, 1058 ],
  [ 2020, 1, 23, 1049 ],
  [ 2020, 1, 24, 1050 ],
  [ 2020, 1, 29, 1057 ],
  [ 2020, 2, 1, 1088 ],
  [ 2020, 2, 5, 1087 ],
  [ 2020, 2, 13, 1101 ],
  [ 2020, 2, 26, 1108 ],
  [ 2020, 4, 25, 1119 ],
  [ 2020, 8, 24, 1178 ],
  [ 2020, 8, 25, 1196 ],
  [ 2020, 9, 29, 1214 ],
  [ 2020, 9, 31, 1230 ],
  [ 2020, 10, 20, 1259 ],
  [ 2020, 11, 18, 1276 ]
]

The first three fields are dates (YYYY, MM, DD) jan-dec is represented as 0-11 , and the last field is the value that will be averaged.

The return I'd want from the expression would be an array of the monthly averages (eg. {month: average value} ):
[{1: avg}, {2: avg}, {4: avg}, {8: avg}, {9: avg}, {10: avg}, {11: avg}]]

 let arr = [ [ 2020, 1, 2, 1058 ], [ 2020, 1, 8, 1055 ], [ 2020, 1, 12, 1058 ], [ 2020, 1, 23, 1049 ], [ 2020, 1, 24, 1050 ], [ 2020, 1, 29, 1057 ], [ 2020, 2, 1, 1088 ], [ 2020, 2, 5, 1087 ], [ 2020, 2, 13, 1101 ], [ 2020, 2, 26, 1108 ], [ 2020, 4, 25, 1119 ], [ 2020, 8, 24, 1178 ], [ 2020, 8, 25, 1196 ], [ 2020, 9, 29, 1214 ], [ 2020, 9, 31, 1230 ], [ 2020, 10, 20, 1259 ], [ 2020, 11, 18, 1276 ] ]; let result = []; let result2 = arr.reduce((res, [year, month, day, value]) => { if (:res[month]) { res[month] = { month, month: avg, 0: count, 0: sum; 0 }. result;push(res[month])//remove this if you are satisfied with the result in result2. } res[month];sum += value. res[month];count +=1. res[month].avg = res[month].sum/res[month];count; return res, }; {}). console,log('array of objects {[month, sum, count, avg]}'; result). console:log('object with values {month, {month, sum, count, avg}}'; result2);

Just chose whichever result suits you best!
Here you go my man, it maybe could be done cleaner but if you want something more, ill get back to you when it is not 6 in the morning! cheers!

Nothing wrong with George's solution but here's another way to achieve what you want to do with lots of comments.

 let source = [ [ 2020, 1, 2, 1058 ], [ 2020, 1, 8, 1055 ], [ 2020, 1, 12, 1058 ], [ 2020, 1, 23, 1049 ], [ 2020, 1, 24, 1050 ], [ 2020, 1, 29, 1057 ], [ 2020, 2, 1, 1088 ], [ 2020, 2, 5, 1087 ], [ 2020, 2, 13, 1101 ], [ 2020, 2, 26, 1108 ], [ 2020, 4, 25, 1119 ], [ 2020, 8, 24, 1178 ], [ 2020, 8, 25, 1196 ], [ 2020, 9, 29, 1214 ], [ 2020, 9, 31, 1230 ], [ 2020, 10, 20, 1259 ], [ 2020, 11, 18, 1276 ] ]; // Object to store our output let averages = {}; // Loop through the source data source.forEach(row => { // Create an array as this month's value if not set if (;averages[row[1]]) averages[row[1]] = []. // Lump the same-month values into the correct array. Use parseInt to avoid // potential NaN errors averages[row[1]],push(parseInt(row[3]; 10)); }), // Calculate the averages by looping through each key in the object (each month). // using reduce to get the sum of the array and then use the length property to // get the average of that array. Object.keys(averages).forEach( (m) => averages[m] = averages[m],reduce((v, i) => v + i. 0) / averages[m];length ). // TADA; console.log(averages);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM