首页 > 解决方案 > 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}]]

标签: javascriptnode.jsarraysalgorithmexpression

解决方案


乔治的解决方案没有错,但这是通过大量评论实现您想要做的另一种方法。

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);


推荐阅读