Use the reduce Method to Analyze Data reduce error

Tell us what’s happening:
I feel so close to finishing this one. I have the filter
returning only the christopher nolan movies, and then map which is giving me the rating. how do I grab the rating section and put it through the reduce() higher order function? I know sum will add up all the values but I thought if i used watchList.length would give me the average. How do i pull from the item.imdbRating?

**Your code so far**
  // Only change code below this line
  let averageRating = watchList
    .filter((movie) => {
      if (movie.Director === "Christopher Nolan") {
        return movie;
      }
    })
    .map((item) => {
      return {
        title: item["Title"],
        director: item["Director"],
        rating: item["imdbRating"],
      };
    })
    .reduce((sum) => {
      return sum;
    });

  // Only change code above this line

  return averageRating;

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36.

Challenge: Use the reduce Method to Analyze Data

Link to the challenge:

Can you paste your code in here please, so we can see where you’re at currently?

oops . sorry about that, didn’t realize the size limit cut it off!

1 Like

So lets deconstruct this.

  1. Filter for the Nolan movies. :white_check_mark:
  2. Map each movie to a rating. :white_check_mark:
  3. Reduce all ratings into a single sum.
  4. Calculate the average.

Questions regarding step 3:

  • What does every reducer need to actually work?
  • What do you want the reducer to calculate in each step?

Thanks for your reply! So that’s what I figured too, my problem is when I get sum I’m not actually getting sum, I’m getting 8.3 and I don’t know why? Am I not accessing the imdb rating properly? I think that’s where my confusion is because I can access the ratings via .map and item parameter but don’t know how to carry that over to reduce !

@miku86

Yeah man, I just am not getting this. The reducer takes the first value (accumulator ) and cycles through the array by adding to each successive value. I am using a current and total to add up to a sum FIRST. However, When i do that I just get [object Object][object Object] etc for the length of the array. If i can figure this portion out, I can just divided it by array.length. But I don’t understand why when I console.log (current, total) I have the ratings, but when I attempt to return , I get this [object Object]

function getRating(watchList){
  // Only change code below this line
  let averageRating = watchList
  .filter(movie => {
        if(movie.Director === 'Christopher Nolan'){
          return movie; 
        }
      })
  .map(item =>{
          // return {title: item['Title'],
          //         director: item['Director'],
          // console.log(item.imdbRating); 
                    return {rating: item['imdbRating']}; 
                   
      })     
  .reduce((accumulator, currentValue) =>{
        console.log(accumulator + currentValue)
     
        
  })


  // Only change code above this line
  return averageRating ;
}
console.log(getRating(watchList));

This is what your map returns for every item, an object.

So when you reduce it, this will also be the data structure of your currentValue.

I think before writing the reducer callback algorithm, it is a good idea to think about the start value of accumulator and add it behind the reducer callback, because this will remind you which output data structure you want to get:

.reduce(() => {
  ...
}, ???)

So what do you want to return from the reducer? An object? A number?

I’m not quite sure I understand what you mean. the start value of accumulator. Wouldn’t that be the first index of the array?

I would like to return back a number. I understand that if i enter the start value at the end it will initiate from 0, correct?

["a", "b", "c"].reduce((acc, cur) => {
  console.log("acc", acc); // "", "a", "ab"
  console.log("cur", cur); // "a", "b", "c"
  return acc + cur;
}, "");

// "abc"

The start value of acc is always the value behind the reducer function, here "".
In the first iteration, cur is "a", then "b", then "c".
In each iteration, you look what is in acc from the last iteration and then add cur.

In this case (slightly modified), your acc start with 0.
Your reducer takes acc (= 0) and adds cur (= {rating: [some imdb rating]}, because you mapped the item to this in your map function.

  // Only change code below this line
  let averageRating = watchList
  .filter(movie => {
        if(movie.Director === 'Christopher Nolan'){ 
        } return true
      })
  .map(item =>{
    let rating = item.imdbRating
          // return {title: item['Title'],
          //         director: item['Director'],
             return rating;       

      })    
  .reduce((acc, currentValue) =>{
        return acc + currentValue / rating.length; 
  }, 0)


  // Only change code above this line
  return averageRating;
}
console.log(getRating(watchList));

Okay, So what I did try to do is assign the item.imdbRating to a variable (rating) because trying to do it as an object it gives me [objectObject] and I don’t know how to have it prinout correctly otherwise. So I attempted to use the length of that variable i.e. acc + currentValue / rating.length I get a totally incorrect result, but not sure why? The goal is to get 8.675