Digamos que tengo una matriz de objetos que contienen información sobre todos los exámenes presentados durante un período de tiempo. Su estructura es así:
[ { name: 'Freddy', grade: 10, date: '20/07/2022' }, { name: 'Jose', grade: 8, date:'20/07/2022' }, { name: 'Freddy, grade: 8', date: '25/07/2022' }, { name: 'Daniel', grade: 5, date: '21/07/2022' }, { name: 'Jose', grade: 5 }, date: '22/07/22', ]Lo que necesito es ignorar el valor de la fecha y simplemente calcular la calificación promedio de cada estudiante y obtener una matriz simple como esta:
[9, 6.5, 5]Ahora digamos que quiero que la matriz siga un orden específico, entonces, ¿cómo puedo reorganizarla siguiendo este orden: Freddy -> José -> Daniel?
Parece un poco extraño, pero necesito que el resultado sea así para usarlo como un conjunto de datos para Chart.js más adelante.
Para hacer esto:
Usé reduce para crear un diccionario que tenga la suma de calificaciones y el recuento de calificaciones de cada estudiante.
reduce itera a través de la matriz. Luego usé Object.keys() para obtener una matriz de las claves del diccionario y map esa matriz en una matriz que tiene un objeto para la calificación promedio de cada estudiante.
Luego map la matriz de objetos solo a los promedios.
const students = [ { name: 'Freddy', grade: 10, date: '20/07/2022' }, { name: 'Jose', grade: 8, date:'20/07/2022' }, { name: 'Freddy', grade: 8, date: '25/07/2022' }, { name: 'Daniel', grade: 5, date: '21/07/2022' }, { name: 'Jose', grade: 5 , date: '22/07/22'} ] const grouped = students.reduce( (output, student) => { const name = student.name if (output[name]) { output[name].gradeTotal += student.grade; output[name].count += 1; } else { output[name] = { gradeTotal: student.grade, count: 1 } } return output }, {}) console.log('Grouped by student: ', grouped) const studentAverages = Object.keys(grouped).map(name => ( { name, average: grouped[name].gradeTotal / grouped[name].count } ) ) console.log('Student averages: ', studentAverages) const justAverages = studentAverages.map(student => student.average) console.log('Just averages:', justAverages)Creo que eso es lo que quieres.
sum , counter para contar la ocurrencia de cada nombre, average y avgArr para almacenar los promediosname . El bucle interno recorre la matriz, busca el nombre y calcula el average para cada persona. Luego agregue este average a la matriz avgArr .checked a cada objeto para evitar tomar el mismo objeto más de una vez si es true , omita ese objeto, si el objeto no tiene esta propiedad, tome este objeto, agregue la propiedad checked y configúrela en true . Si no desea esta propiedad, puede eliminarla más tarde. let arr =[ { name: 'Freddy', grade: 10, date: '20/07/2022' }, { name: 'Jose', grade: 8, date:'20/07/2022' }, { name: 'Freddy', grade: 8, date: '25/07/2022' }, { name: 'Daniel', grade: 5, date: '21/07/2022' }, { name: 'Jose', grade: 5 , date: '22/07/22' }]; let sum = 0; let counter = 0; let avg; const avgArr = []; for (const i of arr){ let name = i.name; if (i.checked === true) { continue; } for (const j of arr){ if (name === j.name) { j.checked = true; sum += j.grade; counter +=1; } } avg = sum / counter; avgArr.push(avg); sum = counter = 0; } console.log(avgArr); // [9, 6.5, 5]