Use the filter Method to Extract Data from an Array: Without parseFloat

Hello,

https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/functional-programming/use-the-filter-method-to-extract-data-from-an-array
Why my solution works without this line ? :
newWatchList.forEach(a => parseFloat(a.imdbRating))

// The global variable
var watchList = [
  {
    "Title": "Inception",
    "Year": "2010",
    "Rated": "PG-13",
    "Released": "16 Jul 2010",
    "Runtime": "148 min",
    "Genre": "Action, Adventure, Crime",
    "Director": "Christopher Nolan",
    "Writer": "Christopher Nolan",
    "Actors": "Leonardo DiCaprio, Joseph Gordon-Levitt, Elliot Page, Tom Hardy",
    "Plot": "A thief, who steals corporate secrets through use of dream-sharing technology, is given the inverse task of planting an idea into the mind of a CEO.",
    "Language": "English, Japanese, French",
    "Country": "USA, UK",
    "Awards": "Won 4 Oscars. Another 143 wins & 198 nominations.",
    "Poster": "http://ia.media-imdb.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
    "Metascore": "74",
    "imdbRating": "8.8",
    "imdbVotes": "1,446,708",
    "imdbID": "tt1375666",
    "Type": "movie",
    "Response": "True"
  },
  {
    "Title": "Interstellar",
    "Year": "2014",
    "Rated": "PG-13",
    "Released": "07 Nov 2014",
    "Runtime": "169 min",
    "Genre": "Adventure, Drama, Sci-Fi",
    "Director": "Christopher Nolan",
    "Writer": "Jonathan Nolan, Christopher Nolan",
    "Actors": "Ellen Burstyn, Matthew McConaughey, Mackenzie Foy, John Lithgow",
    "Plot": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
    "Language": "English",
    "Country": "USA, UK",
    "Awards": "Won 1 Oscar. Another 39 wins & 132 nominations.",
    "Poster": "http://ia.media-imdb.com/images/M/MV5BMjIxNTU4MzY4MF5BMl5BanBnXkFtZTgwMzM4ODI3MjE@._V1_SX300.jpg",
    "Metascore": "74",
    "imdbRating": "8.6",
    "imdbVotes": "910,366",
    "imdbID": "tt0816692",
    "Type": "movie",
    "Response": "True"
  },
  {
    "Title": "The Dark Knight",
    "Year": "2008",
    "Rated": "PG-13",
    "Released": "18 Jul 2008",
    "Runtime": "152 min",
    "Genre": "Action, Adventure, Crime",
    "Director": "Christopher Nolan",
    "Writer": "Jonathan Nolan (screenplay), Christopher Nolan (screenplay), Christopher Nolan (story), David S. Goyer (story), Bob Kane (characters)",
    "Actors": "Christian Bale, Heath Ledger, Aaron Eckhart, Michael Caine",
    "Plot": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, the caped crusader must come to terms with one of the greatest psychological tests of his ability to fight injustice.",
    "Language": "English, Mandarin",
    "Country": "USA, UK",
    "Awards": "Won 2 Oscars. Another 146 wins & 142 nominations.",
    "Poster": "http://ia.media-imdb.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
    "Metascore": "82",
    "imdbRating": "9.0",
    "imdbVotes": "1,652,832",
    "imdbID": "tt0468569",
    "Type": "movie",
    "Response": "True"
  },
  {
    "Title": "Batman Begins",
    "Year": "2005",
    "Rated": "PG-13",
    "Released": "15 Jun 2005",
    "Runtime": "140 min",
    "Genre": "Action, Adventure",
    "Director": "Christopher Nolan",
    "Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
    "Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
    "Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
    "Language": "English, Urdu, Mandarin",
    "Country": "USA, UK",
    "Awards": "Nominated for 1 Oscar. Another 15 wins & 66 nominations.",
    "Poster": "http://ia.media-imdb.com/images/M/MV5BNTM3OTc0MzM2OV5BMl5BanBnXkFtZTYwNzUwMTI3._V1_SX300.jpg",
    "Metascore": "70",
    "imdbRating": "8.3",
    "imdbVotes": "972,584",
    "imdbID": "tt0372784",
    "Type": "movie",
    "Response": "True"
  },
  {
    "Title": "Avatar",
    "Year": "2009",
    "Rated": "PG-13",
    "Released": "18 Dec 2009",
    "Runtime": "162 min",
    "Genre": "Action, Adventure, Fantasy",
    "Director": "James Cameron",
    "Writer": "James Cameron",
    "Actors": "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
    "Plot": "A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
    "Language": "English, Spanish",
    "Country": "USA, UK",
    "Awards": "Won 3 Oscars. Another 80 wins & 121 nominations.",
    "Poster": "http://ia.media-imdb.com/images/M/MV5BMTYwOTEwNjAzMl5BMl5BanBnXkFtZTcwODc5MTUwMw@@._V1_SX300.jpg",
    "Metascore": "83",
    "imdbRating": "7.9",
    "imdbVotes": "876,575",
    "imdbID": "tt0499549",
    "Type": "movie",
    "Response": "True"
  }
];

// Only change code below this line
let newWatchList = watchList.slice(0);
//newWatchList.forEach(a => parseFloat(a.imdbRating))
//console.log(newWatchList)
let filterednewWatchList = newWatchList.filter(item => item.imdbRating >= 8.0)
let filteredList = filterednewWatchList.map(item => ({
  title: item["Title"],
  rating: item["imdbRating"]
}));

// Only change code above this line

console.log(filteredList);

That line doesn’t do what you think it does. The forEach method doesn’t change the array and doesn’t return anything. It’s basically just a for loop. It is the equivalent to:

for (let i = 0; i <newWatchList.length; i++) {
  parseFloat(newWatchList[i].imdbRating)
}

What does that do? It parses a float out of that and then does nothing with it.

Why do you think you need to parse a float out of it? What is wrong with leaving it a string?

I apologize in advance if you have the impression that I am not responding well because I am not very good in English.
I don’t well understand

However, I had also noticed that newWatchList.forEach(a => parseFloat(a.imdbRating)) didn’t work but it was just after send this post to you.
In fact I was obligated to remove my solution with the for loop because it’s forbiden for this exercice:
Look at what I had did:


for (let i =0; i < newWatchList.length; i++ ) {
  newWatchList[i].imdbRating = parseFloat(newWatchList[i].imdbRating);
}

But apparently it’s not as correct as your solution :upside_down_face:

it is because in the statement of the exercise it says:

“Note that the rating values are saved as strings in the object and you may need to convert them into numbers to perform mathematical operations on them.”

OK, your for loop there will work, that makes sense. You could also do it inside the callback to the map method - that is a better place to do it. Give that a try.

“Note that the rating values are saved as strings in the object and you may need to convert them into numbers to perform mathematical operations on them.”

Performing a mathematical operation on and mutating the data are two different things. I’m guessing that they want that to stay a string (it allows better control over how many decimal places show). So, I think that what they are implying is that you may want to do that in your calculations in your filter so that you are comparing numbers to numbers. Of course, I believe that strings will still work since I think JS will coerce those strings to numbers, but implicit type coercion like that can lead to confusion so it probably is wise to do the coercion explicitly.

Does that makes sense?

I don’t undersatnd

I was preparing an other post for you before I received you answer . I think that is in link with what you said:


I rewrote my code and with or without “parseFloat”, that’s works:

1

let newWatchList = watchList.slice(0);

let filterednewWatchList = newWatchList.filter(item => parseFloat(item.imdbRating) >= 8.0)

let filteredList = filterednewWatchList.map(item => ({
  title: item["Title"],
  rating: item["imdbRating"]
}));

2

let newWatchList = watchList.slice(0);

let filterednewWatchList = newWatchList.filter(item => item.imdbRating >= 8.0)

let filteredList = filterednewWatchList.map(item => ({
  title: item["Title"],
  rating: item["imdbRating"]
}));

I don’t undersatnd

You might read here.


Based on my understanding of how JS coerces, those should both work exactly the same. One might argue that the first one is better because it does not rely on the “mystical” and sometimes confusing world or implicit type conversion. One of the complaints about JS is that it is very light and loose with types, one of the reasons why some people like things like TypeScript. So many people (myself included), when writing in JS, try to be explicit with type coercion. What you have will work fine. I might also suggest that a unary plus operator would work just as well:

item => +item.imdbRating >= 8.0

I will study all this. thanks for your help Kevin. :wink:

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.