TonyV
August 12, 2022, 10:45pm
1
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.
TonyV
August 13, 2022, 12:29am
3
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.
TonyV
August 13, 2022, 11:00am
4
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.
ILM
August 13, 2022, 2:10pm
5
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.
TonyV
August 13, 2022, 2:54pm
7
I have control.logged the filtered list and it seems to be an array with only the proper films included.
TonyV
August 13, 2022, 3:03pm
8
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.
TonyV
August 13, 2022, 5:03pm
10
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?
TonyV
August 13, 2022, 5:26pm
12
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;
TonyV:
filteredList.sum
This is not defined
TonyV:
filteredList.count
This is not defined.
TonyV:
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 });
Where did you store the reduced result?
TonyV
August 13, 2022, 8:49pm
14
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.
TonyV
August 13, 2022, 9:15pm
16
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.
TonyV
August 13, 2022, 9:21pm
18
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?
TonyV
August 13, 2022, 9:27pm
20
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.