Use the Reduce() method to analyze data

OK. I am still trying to get the hang of map, filter, reduce. It doesn’t seem complicated but I keep getting caught up in the syntax. Can someone take a look at my code and answer the following questions:

1 - Can a variable created in one part of map, filter, reduce (if combining the methods in a function) be used in another part? See the code that is commented out. I might be basing this on what I know about for loops which is a tough mindset to get out of.

2 - When my own attempt to set the denominator variabldidn’t work, I finally caved and looked at the solution. What they did makes perfect sense but when I put it in my code, I get one of 2 incorrect answers:
a. if code is return (x + y)/… then I get 2.9
b. if code is return x + y/…then I get 15.27

I checked the values of x+y and watchList.filter(x => x.Director === “Christopher Nolan”).length separately. They are both right, i.e. 34.7 and 4, respectively.

My code:

var averageRating = watchList
    .filter(function(eachitem){
        return eachitem["Director"] === "Christopher Nolan";
        // let denominator = (eachitem["Director"] === "Christopher Nolan").length;
        // console.log(denominator);
    })
    .map(function(element){
        return Number(element["imdbRating"]);
    })
    .reduce(function(x,y){
      return x + y/watchList.filter(x => x.Director === "Christopher Nolan").length;
    });

// Add your code above this line

console.log(averageRating);

Thank you.

Hi @sabbyiqbal,

  1. I’m not exactly sure what you mean, did you mean if you could use a variable created in .map() and use it in .filter()? Thats not possible because variables are block/function scoped so they only exist in the callback function of those HOF’s.

  2. The problem with you code is that you’re dividing the sum with the length each iteration.
    x + y/watchList.filter(x => x.Director === "Christopher Nolan").length; This code executes every iteration, so first in first iteration its 8.8 + 8.6 /4 then in next its the previous avg / 4 and so on.

To fix you could divide it by the length after the reduce is completed like:

reduce(function(x,y){
      return x + y;
    }/watchList.filter(x => x.Director === "Christopher Nolan").length;

Thanks - that worked! Final code:

var totalRating = watchList
    .filter(function(eachitem){
        return eachitem["Director"] === "Christopher Nolan";
    })
    .map(function(element){
        return Number(element["imdbRating"]);
    })
    .reduce(function(x,y){
      return x + y;
    });

var averageRating = totalRating/watchList.filter(x => x.Director === "Christopher Nolan").length

// Add your code above this line

console.log(averageRating);