var averageRating = watchList
.filter(movie => {return movie.Director=="Christopher Nolan"})
.reduce((sum, nolanMovies) => {
return (sum + parseFloat(nolanMovies.imdbRating));
},0)
/(watchList.filter(movie => {return movie.Director=="Christopher Nolan"}).length); // <--there has to be a better //way.
;
while this works, I feel it is kind of ugly. As you can see, I could filter out the movie list and get the sum of the ratings but didn’t know how to get the amount of movies there are without invoking the filter method again. I feel like there has to be a better way to do this but I just couldn’t find out. What would be the best way so I can convert the sum of scores into an average?
You could increment your count while calculating sum if your accumulator could hold both values. Like an array [0,0] or an object {sum:0, count:0}. That would give you both numbers in one pass, maybe even calculate average at the end somehow.
EDIT
I figured this out. Maybe it will help you out.
const arr = [10,20,30];
const average = arr.reduce(function(acc,el,ind,ar){
acc = [acc[0]+el, acc[1]+1];
if(ind >= ar.length-1){ // calculate average on last element
acc = acc[0] / acc[1];
}
return acc;
},[0,0]);
console.log(average); //20
Hi, can someone explain the meaning of (acc*index + cur)?
I created a separate array for each step: filter, map then reduce which provides the same answer. The ‘reduce’ method looks like this sum = Rating.reduce((total,item) => (total + parseFloat(item)/Rating.length),0)
So just want to understand how other solution works.
Thanks.