Functional programming explanation

function getRating(watchList){
  // Only change code below this line

  var averageRating =
   watchList
    // Use filter to find films directed by Christopher Nolan
    .filter(elt => elt.Director === "Christopher Nolan")
    // Use map to convert their ratings from strings to numbers
    .map(film => Number(film.imdbRating))
    // Use reduce to add together their ratings
    .reduce((sumOfRatings, rating) => sumOfRatings + rating) /
  // Divide by the number of Nolan films to get the average rating
  watchList.filter(film => film.Director === "Christopher Nolan").length;
  // Add your code above this line
  return averageRating;;
  // Only change code above this line
  return averageRating;
}

In this solution of

Use the reduce Method to Analyze Data

I really dont 'understand the reduce part : how does the code know that it must add imdbRating value ? This property is not called. I would have write imdbRating instead of rating but obviously that is not the answer.
Anyone can help ? Thanks

This needs to be looked at as a part of few chained operations. There’s few calls - filter, map, reduce. First, filter filters only movies, which are directed by Christopher Nolan. Then map for each movie returns imdbRating. If there weren’t another step - reduce at this point one would get list of ratings. So once reduce is called for each entry it gets only the rating.

1 Like

Yeah, at that point each array element is just a rating. As sanity says, the chaining may be obscuring what is happening. Perhaps if you broke things up like this so you can see what is happening at each step. Something like:

var nolanMovies = watchList.filter(elt => elt.Director === "Christopher Nolan");
console.log(nolanMovies);

var ratingsOnly = nolanMovies.map(film => Number(film.imdbRating));
console.log(ratingsOnly);

var sumRatings = ratingsOnly.reduce((sumOfRatings, rating) => sumOfRatings + rating);
console.log(sumRatings);

var numRatings = nolanMovies.filter(film => film.Director === "Christopher Nolan").length;

var averageRating = sumRatings / numRatings;
2 Likes

I may be reading your question wrong, but since you specifically mentioned “This property is not called”, and that you’d write “imdbRating” instead of “rating”, it seems your confusion is about how the supplied callback function is called?

If this is indeed the case:

  • Try to see that it is an uncalled function that’s passed to the reduce() method.
  • In this context, the passed function is referred to as a “callback function” because the function is not called by you, but called back by some other parts of your code.
  • In this case, the reduce() method will call the callback function on every element of the array, and progressively reduce the return values of all the function calls into a single value (the accumulated value).
  • Every time the reduce() method calls the callback function, it is reduce which decides what arguments to pass to the callback function: it will always pass the accumulated value as the first argument, the current array element as the second argument, the current array index as the third argument, and the entirety of the array on which reduce is called as the fourth argument. (Refer to the link above for detailed syntax explanation).

So it doesn’t matter if you write imdbRating or rating, as long as it’s the second parameter, you can name it whatever you want because reduce will always pass the current element as the second argument.

1 Like

Ok. My confusion was about .map : I did not clearly understand that .map performs a sort of “select” i.e. only mentionned property are returned. Thanks.

Just for clarity, it doesn’t.

You give map a function. It runs that function for each item in an array in turn, producing a new array.

But that function has to return a value, so what map does is produce an array with the same number of values, but with each element transformed.

filter does select items. Like map, it runs a for each item in an array in turn, producing a new array.

That function has to return true or false, and if it returns true, the item from the original array goes into the new array.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.