Tengo una matriz de objetos que se ve así:
[{ TIMESTAMP: "2021-05-07 03:32:00.0", PM2_5: "27.4", PM10: "67.9", CO: "0.058", }, { TIMESTAMP: "2021-05-07 03:42:00.0", PM2_5: "27.0", PM10: "67.3", CO: "0.026", }, { TIMESTAMP: "2021-05-07 04:08:00.0", PM2_5: "27.0", PM10: "67.3", CO: "0.066", } ...]Hay más datos ofc. Quiero hacer una función que tome mi matriz como parámetro y devuelva una matriz de objetos. En esta matriz de retorno, quiero fusionar todos los objetos con la misma marca de tiempo de hora y hacer un promedio de todas sus propiedades. No sé qué propiedad tendrán y el número puede variar. Para que pueda tener un objeto por cada hora. Por ejemplo para todo el objeto a las 3h, tendré
{ TIMESTAMP: "2021-05-07 03:00:00.0", PM2_5: "27.2", PM10: "67.3", CO: "0.046", }Para el rango de 3 horas, tendré el promedio de todos los datos en un solo objeto. Y quiero hacer esto durante todas las horas que pueda tener en la matriz. Traté de usar reduce, o hacer un bucle grande, pero mi problema es que no quiero precisar la clave en mi bucle, quiero que funcione para todas las claves que puedan existir.
function getAverage(datas) { const res = [] datas.forEach((data, i) => { if (moment.tz(data.TIMESTAMP, 'YYYY-MM-DD HH:mm:ss', TIMEZONE).hour() === moment.tz(datas[i + 1].TIMESTAMP,'YYYY-MM-DD HH:mm:ss', TIMEZONE).hour()) { data += data.PM10 } res.push(data / i) i = 0 }) return res }Hice eso por ahora, pero está muy lejos del resultado que quiero.
He generado una lógica personalizada para generar la salida según el requisito.
Puede encontrar los detalles de la lógica y la implementación en el comentario del código.
violín de trabajo
const data = [{ TIMESTAMP: "2021-05-07 03:32:00.0", PM2_5: "27.4", PM10: "67.9", CO: "0.058", }, { TIMESTAMP: "2021-05-07 03:42:00.0", PM2_5: "27.0", PM10: "67.3", CO: "0.026", }, { TIMESTAMP: "2021-05-07 04:08:00.0", PM2_5: "27.0", PM10: "67.3", CO: "0.066", }]; function getAverage(datas) { const output = datas.reduce((acc, curr) => { // Convert the date string. // Replace all minutes and seconds with :00 // Replace milliseconds with .0 const timestr = curr.TIMESTAMP .replaceAll(/:\d{2}/gm, ":00") .replaceAll(/\.\d/gm, ".0"); // If the node with this parsed date string is avilable in accumulator, modify that node if (acc[timestr]) { // Increment the total against that particular timestamp ++acc[timestr].total; // Generate unique keys from the node in accumulator and from the current node in the data array const keys = [...new Set([...Object.keys(acc[timestr]), ...Object.keys(curr)])]; // Loop through the keys and add that to node in accumulator. keys.forEach((key) => { // Donot modify key 'TIMESTAMP' if (key !== 'TIMESTAMP') { acc[timestr][key] = (+acc[timestr][key] || 0) + (+curr[key] || 0); } }) } else { // If the node with this parsed date string is not available in accumulator, add that node acc[timestr] = { ...curr, TIMESTAMP: timestr, total: 1 }; } return acc; }, {}); // Generate average // The result of accumulator is an object // Convert it into Array using `Object.values(output)` and run `Array.map` const result = Object.values(output).map((node) => { // create an object rest from the value with out key total and TIMESTAMP const { total, TIMESTAMP, ...rest } = node; // Find avarage of each key Object.entries(rest).forEach(([key, value]) => rest[key] = +rest[key] / total); // Return parsed node return { ...rest, TIMESTAMP }; }) return result; } console.log(getAverage(data));