.
A este punto espero ya entiendas cual es el propósito de este texto, y si no, igual lo pongo para hacer espacio en este comentario (no olvides darle like).
.
Este es un comentario para aquellos y aquellas estudiantes que sea su primera vez resolviendo este coding playground y evites auto spoilearte viendo las soluciones de la comunidad (por favor SIGAN compartiendo sus soluciones, nos fascina ver como lo hacen). A su vez, este comentario tendrá la explicación a este problema más abajo, abajo del gif random que siempre suelo poner por lo que ya sabes que esperar si haces más scroll
.
Momento random del día
!dog
.
Explicación
En este caso, no optamos por usar bucles. En su lugar fueron métodos propios de los arrays (para variar con las soluciones pero facilmente puede hacerse con un for o un while, for of, etc...)
exportfunctiongetStudentAverage(students){// Creamos un array donde obtendremos los estudiantes con su promedioconst studentsWithAverage = students.map((student)=>{// separamos las notas en una sola variable para hacerlo más legibleconst grades = student.grades;// calculamos el promedio sumando todas las notas para dividirlas// en el total de materiasconst average = grades.reduce((total, item)=> total + item,0)/ grades.length;return{// Retornamos un objeto con el nombre del estudiantename: student.name,// Junto con su promedio a 2 decimales// Es importante parsearlo con Number porque el método toFixed devuelve un stringaverage:Number(average.toFixed(2)),};});// Después pasamos a hacer lo mismo pero obteniendo el promedio de la claseconst classAverage = studentsWithAverage.reduce((total, student)=> total + student.average,0)/ studentsWithAverage.length;// Sumamos todos los promedios y los dividimos entre el total de estudiantes// Al final armamos un objeto que será el que retornaremosconst rta ={// De igual manera pasamos el promedio de la clase a 2 decimalesclassAverage:Number(classAverage.toFixed(2)),students: studentsWithAverage,};// Y retornamos el objeto anteriorreturn rta;}
Y ¡listo!
.
Si llegaste a esta parte de la lectura te comparto un fun fact, esta solución fue propuesta por el gran Nicobytes, mi solución era otra pero esta se ve más coqueta.
.
No olvides dejar tu corazoncito
Gente aquí vengo yo a que no vean las respuestas de los demás
+
+
+
+
+
+
+
+
+
+
+
Más limpio
Escudo anti spoilers
exportfunctiongetStudentAverage(students){// Tu código aquí 👈let total =0;const course ={classAverage:0,students:[]};for(const student of students){let sum = student.grades.reduce((sum, grade)=> sum + grade);let averageStudent =(sum / student.grades.length).toFixed(2);const aStudent ={name: student.name,average:Number(averageStudent)} course.students.push(aStudent); total +=Number(averageStudent);} course.classAverage=Number((total / students.length).toFixed(2));return course;}
Por favor no más loops dentro de loops, me estoy lastimando :(
exportfunctiongetStudentAverage(students){const final ={classAverage:0,students:[]};const arrayPromedioFinal =[];let promedioFinal;for(let objeto of students){const promedio = objeto["grades"].reduce((a, b)=> a + b); arrayPromedioFinal.push(Number((promedio / objeto["grades"].length).toFixed(2))); promedioFinal = arrayPromedioFinal.reduce((a, b)=> a + b)/ students.length; final.classAverage=Number(promedioFinal.toFixed(2)); final.students.push({name: objeto.name,average:Number((promedio / objeto["grades"].length).toFixed(2)),},);};return final;}
Hey dude, aqui mi solución :
functiongetStudentAverage(students){//Primero, creamos una variable totalAverage que utilizaremos para acumular los promedios individuales de cada estudiantelet totalAverage =0;//Luego, iteramos a través del array de estudiantes usando el método map() y calculamos el promedio de cada estudiante usando el método reduce().const studentAverages = students.map(student=>{const average = student.grades.reduce((sum, grade)=> sum + grade,0)/ student.grades.length;//Dentro del map(), también agregamos el promedio del estudiante a la variable totalAverage y redondeamos el promedio a dos decimales usando el método toFixed(). totalAverage += average;return{name: student.name,average:Number(average.toFixed(2))};});//Después de calcular los promedios individuales de cada estudiante, calculamos el promedio de la clase dividiendo totalAverage por la cantidad de estudiantes y redondeando el resultado a dos decimales.const classAverage =Number((totalAverage / students.length).toFixed(2));//Creamos el objeto de salida con los valores correspondientes y lo retornamos.return{classAverage:Number(classAverage),students: studentAverages
};}
Muy buena solucion!
Gracias por. compartir
gracias por los comentarios
La siguiente función genera un error en este entorno de ejecución de pruebas, sin embargo… funciona si lo pruebas en tu terminal con Node.js, o directamente en la consola de tu navegador.
/**
* Proccess the data to get the average of the class and the average of each student.
*
* @param{Array<Object>}students - Array of objects with name and grades properties.
* @returns{Object} Object with classAverage and students with name and average properties.
*/functiongetStudentAverage(students){let classAverage =0for(const student of students){const grades = student.gradeslet average = grades.reduce((a, b)=> a + b)/ grades.length average =+average.toFixed(2)delete student.grades student.average= average
classAverage += average
} classAverage =+(classAverage / students.length).toFixed(2)return{ classAverage, students }}
Identificación del problema:
Logré identificar que el problema solo sucede cuando uso la palabra clave delete para borrar la propiedad grades del objeto student. En este caso consideré mejor utilizar delete, en vez de desestructuración, ya que en este caso no consideré necesario crear un nuevo array de objetos student, ya que no requiero eliminar muchas propiedades del mismo, en realidad solo requiero eliminar una propiedad de los objetos student contenidos en el array students, por lo que tampoco consideré necesario aplicar un map, y retornar un nuevo array de nuevos objetos con las propiedades que requiero, por cada objeto del array.
Contextualización (delete vs desestructuración):
const obj ={prop1:'Valor 1',prop2:'Valor 2',prop3:'Valor 3'}// Ejemplo de eliminación de propiedad con deletedelete obj.prop2console.log(obj);// { prop1: 'Valor 1', prop3: 'Valor 3' }// Ejemplo de desestructuración de objetoconst{ prop2,...rest }= obj
console.log(prop2);// 'Valor 2'console.log(rest);// { prop1: 'Valor 1', prop3: 'Valor 3' }
Solución:
Aunque no era mi intención resolverlo de esta manera, esta fue la mejor solución alternativa que se me ocurrio para que funcionara en el entorno de ejecución de pruebas de platzi:
functiongetStudentAverage2(students){let classAverage =0 students = students.map(student=>{const grades = student.gradeslet average = grades.reduce((a, b)=> a + b)/ grades.length average =+average.toFixed(2) student.average= average
classAverage += average
return{name: student.name, average
}}) classAverage =+(classAverage / students.length).toFixed(2)return{ classAverage, students }}
Si bien algunos de mis propósitos aquí son mejorar y seguir aprendiendo, y entiendo que hay diversas soluciones alternativas y algunas serán más adecuadas para este caso que otras, no me siento conforme :( ya que no entiendo porque la primera solución que se me ocurrió, no funciona aquí... Ya que si comparo los resultados que arrojan ambas soluciones que propuse, son exactamente iguales :/
Y se preguntarán entonces: por qué esto es una pregunta y no un aporte. Bueno... si bien existen alternativas a delete, el hecho de que no se pueda utilizar aquí, me genera dudas.
Suposición:
La palabra clave delete no está soportada en este entorno de ejecución de pruebas JS.
Dudas:
¿Por qué razón sucede esto, el hecho de que no se pueda usar delete, acaso tiene que ver con la seguridad del entorno de ejecución de pruebas y una restricción del mismo, o acaso es algo más, quizá algo que ni siquiera tenga que ver con delete?
¡Hola, Santiago!
/
Te tengo una buena y una mala noticia.
/
La buena es que delete si es soportado por el playground y tu solución está perfecta.
/
La mala, es que tu código lo que hace es modificar el array original mismo array que es usado para las siguientes pruebas y por eso te da un error de grades is undefined dentro del playground.
/
¿Por qué sucede esto?
Bueno para serte sincero, no pensamos que alguien usara mutable functions para los ejercicios básicos pero NO queremos limitarte a soluciones básicas.
/
De entrada te ofrezco una disculpa por esta mala experiencia y te agradezco por el feedback, ya mismo mande el fix para este ejercicio y tu solución funcione sin problema alguno (te avisaremos cuando esto pase).
/
Por ahora te ofrezco otro reto adicional, tu solución pasa sin ningún problema si haces un deep copy del array. Y así trabajas con una copia del input.
/
Mil gracias por tus comentarios, te ofrezco unirte al discord oficial de Platzi donde encontrarás un canal específico del reto donde podremos darte una pronta respuesta a este y distintos problemas que llegues a tener.
Un abrazo! 💪
Saludos comunidad platzi lo resolví de esta manera:
Es verdad que lo que yo hice primero fue buscar el promedio total de todos los estudiantes, esto porque no había entendido bien el output, luego entonces fui a sacar el promedio de cada estudiante.
ChatGPT lo que hizo primero fue sacar el promedio de cada estudiante, y luego usarlos para sacar el promedio total del promedio de cada estudiante. Así ahorro espacio en memorio, utilizo menos loops, y tal.
No se por que pero en el playground no me funciona esta solucion mientras que en Node si esta funcionando. Alguien tiene idea de que pasa?
functiongetStudentAverage(arr){let output ={};const students =[]; classAverage =0;for(element of arr){const student ={}; student.name= element.name; student.average=parseFloat(((element.grades.map(x=> x/element.grades.length)).reduce((sum, num)=> sum + num,0)).toFixed(2)); students.push(student);}for(student of students){ classAverage += student.average;} output.classAverage=parseFloat((classAverage/students.length).toFixed(2)); output.students= students;return output;}
¡Hola @Sergio_A!
¡Tu solución está perfecta! El problema por el cual las pruebas no pasan es porque estás omitiendo el declarar algunas variables como la de los ciclos for... of o la variable como classAverage
Simplemente agrega let o const dependiendo el caso y funcionará a la primera 🙌
Un saludo!
Buenas, tengo el codigo asi no me sale correctamente, en consola me muestra que si se esta enviando el arreglo pero cuando envio el objeto completo no funciona 
Se espera que cada objeto de los estudiantes tenga un atributo llamado average pero tu lo tienes como grades
Corrigiendo esto deberías tener un resultado diferente, espero te sea de ayuda
Un abrazo!
Este es el primer reto que completo 100% solo, estoy muy feliz, aunque tengo una duda, si intento dividir el solution.classAverage entre number de una vez dentro del ciclo for, se divide por 6 en lugar de 3, no se por que. Es por eso que tuve que ponerlo afuera de for.
Cabe aclarar que así me funciona, solo que tengo la duda de porque no puedo ponerlo adentro. Aca les dejo la situacion en la que me devuelve solution.classAverage dividido entre 6 en lugar de 3 que es el numero de estudiantes que hay en la vista.
Buenas, hay casos en el que el toFixed(2) me retorna solo un decimal después de la coma, esto me ocurre en los casos donde el segundo decimal es 0, por lo tanto, no pasa algunas de las pruebas. ¿Hay alguna manera de que redondee a dos decimales mostrando el 0 del segundo decimal?
No es necesario que se muestre el 0 ¿Cuál es la prueba que no pasa?
Tenía el error en el cálculo de los promedios de cada estudiante, al parecer era por el tipo de dato, yo efectuaba:
let promedioEstudiante =Number(sumaNotas / cantidadNotas);let studentAverage ={name: student.name,average: promedioEstudiante.toFixed(2),}
Mi error estaba en que al aplicar él .toFixed(2) a promedioEstudiante me lo volvía a dejar como String, lo arregle aplicándole de nuevo un Number() al promedio redondeado.
Aqui les dejo un pequeño aporte
My solution 👇
functiongetStudentAverage(students){const result ={};const studentAverage =[];for(let student of students){const individualAverage = student.grades.reduce((acc, val)=> val + acc,0)/ student.grades.length; studentAverage.push({name: student["name"],average:Number(individualAverage.toFixed(2))});}const generalAverage = studentAverage.reduce((acc, val)=> val.average+ acc,0)/ studentAverage.length; result["classAverage"]=Number(generalAverage.toFixed(2)); result["students"]= studentAverage;return result;}
Reto cumplido xd:
exportfunctiongetStudentAverage(students){let datoEstudiante =[];for(var estudiante of students){ datoEstudiante.push({name: estudiante.name,average:parseFloat(((estudiante.grades.reduce((a, b)=> a + b,0))/ estudiante.grades.length).toFixed(2))});}const object ={classAverage:parseFloat(((students.reduce((a, b)=> a + b.grades.reduce((a, b)=> a + b,0),0))/ students.reduce((a, b)=> a + b.grades.length,0)).toFixed(2)),students: datoEstudiante };return object;}
no se porque qaui no me corre pero esta fue mi solucion: