Functional Programming - Use the reduce Method to Analyze Data

I am getting NaN

My code so far

const filteredList = watchList.filter(checkAdult);

function checkAdult(movie) {
  return movie.Director  == "Christopher Nolan";
}

filteredList.reduce((data, { Director: director, imdbRating: rating }) => {
        data.count++;
        data.sum += Number(rating);
      return data;
    }, { sum: 0, count: 0 });
  const averageRating = filteredList.sum / filteredList.count;

Your browser information:

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

Challenge: Functional Programming - Use the reduce Method to Analyze Data

Link to the challenge:

A helpful tool to see what is going on between the code flow is to use console.log(). That is how I noticed where lies the problem.

Your algorithm does not work only because something is missing in this function:

filteredList.reduce((data, { Director: director, imdbRating: rating }) => {
        data.count++;
        data.sum += Number(rating);
      return data;
    }, { sum: 0, count: 0 });

Try to console.log() the properties you use to calculate the averageRating, to see their values, and to see why your final result is NaN (Not-A-Number).

Hidden Hint:

Read more information about the Array.reduce() function, and about what it returns.

It seems that both top and bottom of the fraction are not defined, but I thought

const filteredList = watchList.filter(checkAdult);

defined filteredList sufficiently. I tried changing it to

const filteredList = watchList.filter(…checkAdult);

Not sure what is going on.

I have inserted a line of code that seems to be very sensitive:


const filteredList = watchList.filter(checkAdult);

function checkAdult(movie) {
  return movie.Director  == "Christopher Nolan";
}

filteredList.reduce((data, {imdbRating: rating }) => {
        data.count++;
        data.sum += Number(rating);
console.log({ data, imdbRating: rating });
      return data;
    }, { sum: 0, count: 0 });
  const averageRating = filteredList.sum / filteredList.count;

when I move the console log down one line however, it does not show anything but the NaN. This is a bit confounding to me.

You have defined filteredList, but are you sure it has those properties?

Your filteredList.reduce() function is updating a value which is an object with the sum and count properties. And it returns a final value. But it is not being saved anywhere.

I have control.logged the filtered list and it seems to be an array with only the proper films included.

I don’t understand how to save the object or to create a different datatype that contains the information. I also don’t understand why my object is different than that of the given solution 2.

You have to assign to a new variable the returned value of the filteredList.reduce() function, or else the returned value gets lost and it is not used.

That variable will be the returned object you created with the function.

Now, you can access their properties, sum and count.

The Array.reduce() function does not change the calling array, only returns a new value.

Here is my new code:


const filteredList = watchList.filter(checkAdult);

function checkAdult(movie) {
  return movie.Director  == "Christopher Nolan";
}

let Totals=filteredList.reduce((data, {imdbRating: rating }) => {
        data.count++;
        data.sum += Number(rating);
console.log({ data, imdbRating: rating }, Totals);
      return data;
    }, { sum: 0, count: 0 });
  const averageRating = filteredList.sum / filteredList.count;

This code is still troubling. I tried finding the variable assignment in the very similar Solution 2 and don’t see it.

Does the filtered list have these properties?

filteredList is just subset of watchlist so it does not. However, I have changed my disfunctional code so that I can go back and forth between my code and Solution 2 and am not understanding your point

/*
  const nolanData = watchList
    .reduce((data, { Director: director, imdbRating: rating }) => {
      if (director === 'Christopher Nolan') {
        data.count++;
        data.sum += Number(rating);
console.log({ data, imdbRating: rating }, nolanData.sum / nolanData.count);
      }
      return data;
    }, { sum: 0, count: 0 });
  const averageRating = nolanData.sum / nolanData.count;
*/

const filteredList = watchList.filter(checkAdult);

function checkAdult(movie) {
  return movie.Director  == "Christopher Nolan";
}

let Totals=filteredList.reduce((data, {imdbRating: rating }) => {
        data.count++;
        data.sum += Number(rating);
console.log({ data, imdbRating: rating }, filteredList.sum / filteredList.count);
      return data;
    }, { sum: 0, count: 0 });
  const averageRating = filteredList.sum / filteredList.count;

This is not defined

This is not defined.

Where did you store the reduced result?

I have given this a shot:

/*
  const nolanData = watchList
    .reduce((data, { Director: director, imdbRating: rating }) => {
      if (director === 'Christopher Nolan') {
        data.count++;
        data.sum += Number(rating);
console.log({ data, imdbRating: rating }, nolanData.sum / nolanData.count);
      }
      return data;
    }, { sum: 0, count: 0 });
  const averageRating = nolanData.sum / nolanData.count;
*/

let filteredList = {count:0, sum:0};
filteredList = watchList.filter(checkAdult);
const data = {count:0, sum:0};
function checkAdult(movie) {
  return movie.Director  == "Christopher Nolan";
}

filteredList.reduce((data, {imdbRating: rating }) => {
        data.count++;
        data.sum += Number(rating);
console.log({ data, imdbRating: rating }, filteredList.sum / filteredList.count);
      return data;
    }, { sum: 0, count: 0 });
  const averageRating = filteredList.sum / filteredList.count;
 

Still no luck. So I ask, can you show me how these are defined in Solution 2, which I commented out.

You still have not fixed this.

filteredList.sum doesn’t exist. filteredList.count doesn’t exist.

The reduce method returns the reduced data.

You stored that into a variable (though most recently you removed the rt where you store the result into a variable, which effectively means you do all that work and throw away the entire result of calling reduce).

You need to use the result of the reduce method. That is where the sum and count exist.

Can you show me where they do this in the given solution 2.

const averageRating = nolanData.sum / nolanData.count;

You need to understand what each variable you are using holds. For that solution, nolanData holds the final result of calling reduce.

I don’t understand how these two lines are different. Where is nolanData defined any differently than filteredList?

const averageRating = nolanData.sum / nolanData.count;

const averageRating = filteredList.sum / filteredList.count;

Because… The filtered list is not where you put the reduced data. Console.log the filteredList variable. What is inside of that variable?

console.log(filteredList) is a subset of watchlist.

console.log(filteredList.sum, filteredList.count) shows they are undefined.

However, in solution 2, console.log( nolanData.sum , nolanData.count) generates a “TypeError: Cannot read properties of undefined (reading ‘sum’)” error.