Utiliza el método "reduce" para analizar datos

Estoy realizando el desafío Utiliza el método “reduce” para analizar datos y algo en mi código no está funcionando.

Copio solo la función:

function getRating(watchList) {
  // Cambia solo el código debajo de esta línea
  let cont = 0;
  let averageRating = watchList.filter(film => film.Director === "Christopher Nolan")
  .reduce((result, film, i) => {
    result += Number(film.imdbRating);
    return result / (i + 1) ;
  }, 0)


  // Cambia solo el código encima de esta línea
  return averageRating;
}

console.log(getRating(watchList)); 

La función debería devolver 8.675 pero me devuelve 3.55.

Dejo también un enlace a CodePen donde copié el código por si alguien quiere verlo ahí.

¡Muchas gracias!

Hola @fgfagundez!
Tu funcion no esta calculado un promedio correctamente.

Al resultado le sumas un rating y luego dividis dicho resultado por la cantidad de peliculas. Perfecto, si hubiera una o dos peliculas funciona.
En el momento que agregas una tercera pelicula o mas, fijate que el resultado ahora contiene ya el promedio entre las primeras dos, y le agregas el rating de una tercera a algo ya promediado y lo volves a repartir ahora por 3.

Un ejemplo numerico:

peliculas = [10, 10, 10] /* El promedio deberia ser 10 */
promedio += pelicula[0] /* promedio es 10 */
promedio /= 1 /* promedio es 10, bien */

promedio += 10 /* promedio es 20 */
promedio /= 2 /* promedio es 10, va bien */

promedio += 10 /* promedio es 20 */
promedio /= 3 /* promedio es 6.67 y deberia ser 10 */

Para el promedio te recomiendo que trates de tomar un acercamiento mas convencional en el que sumas todos los ratings y luego los repartis por la cantidad total.

1 Like

Muchas gracias @ yunsuklee. Ahora realicé la siguiente modificación pero me devuelve undefined.

function getRating(watchList) {
  // Cambia solo el código debajo de esta línea
  let cont = 0;
  let averageRating = watchList
    .filter(film => film.Director === "Christopher Nolan")
    .reduce((result, film, i) => {
      result += Number(film.imdbRating);
    
      let array = watchList.filter(film => film.Director === "Christopher Nolan");

      if(array.length === i-1) {
        return result / array.length;
      }
    }, 0)

  return averageRating;
}

console.log(getRating(watchList)); 

El mejor consejo que te puedo dar es que trates de descubrir por tu cuenta por que te da undefined. Agrega console.logs en todos lados, en todas las variables a medida que se van modificando durante la ejecucion del codigo y hacele un seguimiento e inmediatamente vas a darte cuenta que se puede corregir, o inclusive, si el metodo que estas adoptando para la resolucion es ineficiente.

Si estas familiarizado con las matematicas al respecto, un promedio cae en algebra lineal, por lo que la suma de los promedios individuales es igual al promedio total. La cuestion es que los promedios individuales deben calcularse en base del total, no de una cantidad parcial. En otras palabras, si tenes 5 peliculas, si calculas el promedio de 1 de ellas en base a el total, que son 5 peliculas; haces lo mismo para cada una de ellas y sumas, funciona. Ahora bien, si tenes 5 peliculas, y a medida que vas avanzando la vas calculando el promedio con la cantidad de peliculas que vas viendo estarias calculando 5 promedios distintos.

Es que traté de resolverlo por mi cuenta y no pude, por eso lo publiqué.
Descubrí, publicando en otro foro, que me daba undefined porque .reduce() tiene que devolver return en cada iteración y yo lo tenía dentro de un condicional. Por otro lado, también tenía mal la condición en el if.

Así debería quedar el código:

    .reduce((result, film, i, array) => {
      result += Number(film.imdbRating);      
      
      if (array.length - 1  === i) {
        return result / array.length;
      }
      return result;
    }, 0)

Por otro lado, conozco como se calcula la media aritmética, lo que ocurre que la estaba implmentando mal ya que no estaba considerando el hecho que result es un acumulador y debía calcular el promedio solo en la última iteración.

Muchas gracias!
Saludos!

1 Like