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.
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;
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.
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.