Question re: Functional Programming: Use the filter Method to Extract Data from an Array

Question re: Functional Programming: Use the filter Method to Extract Data from an Array
0

#1

Hi. I’m working through the beta section on functional programming and am on “Use the filter Method to Exract Data.” My solution appears to check out with repl.it and the Chrome console, yet the fcc console won’t pass. Any chance s/one can spot the error I’m missing or is this particular challenge buggy.

I’m omitting the global array for brevity.

// Add your code below this line

var filteredList;

function findRatedTitles(arr){
    filteredList = arr.filter(function(item){
      item.imdbRating = Number(item.imdbRating);
      rating = item.imdbRating;
      if(rating >= 8){
        return rating;
      }
    }).map(function(item){
      var title = item.Title;
      var rating = item.imdbRating;
      var obj = {
        title,
        rating
      };
    return obj;
  });
  return filteredList;
}
findRatedTitles(watchList);

// Add your code above this line

console.log(filteredList);

#2

my suggestion is to move the var filteredList inside your function … dont think fcc like global variables


#3

The expected answer has the rating as a string instead of a number. The following line in your code is converting rating from string to number:

 item.imdbRating = Number(item.imdbRating);

Instead of converting the actual rating to a number, use the rating variable for the conversion. See below:

var filteredList;

function findRatedTitles(arr){
    filteredList = arr.filter(function(item){
//   remove this line   item.imdbRating = Number(item.imdbRating);
      rating = Number(item.imdbRating); // only the variable rating is a number and the original object rating is still string
      if(rating >= 8){
        return rating;
      }
    }).map(function(item){
      var title = item.Title;
      var rating = item.imdbRating;
      var obj = {
        title,
        rating
      };
    return obj;
  });
  return filteredList;
}
findRatedTitles(watchList);

For a more streamlined solution to this challenge, you should try to make use of ES6 arrow functions:

var filteredList = watchList.filter((elem) => Number(elem.imdbRating) >= 8.0)
  .map((elem) => ({title: elem.Title, rating: elem.imdbRating}));

#4

Thank you very much for your help pointing out the problem with item.imdbRating. I resolved the issue by making a copy of arr ( copy = arr.slice(0) ) and thereby isolating the function from the global watchList. I also deleted the unnecessary line you pointed out as well as getting rid of the unneeded Number.


#5

Well, i found this exercie “to easy to be true”. I think i got lucky and i don’t completly understand what i’m doing.
Why lucky ? because i don’t know why it was String and it became number without doing nothing.
And my “greatherThan( obj )”, i understand it but not really the “obj”. I think the obj mean the “filteredList” variable but it make no sense for me. It’s just…as it is and i deal with it.

// 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, Ellen 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"
                }
];

var filteredList = watchList.map( function( obj ) {
	let title = obj.Title;
	let rating = obj.imdbRating;
	
	var myObj = {
		title,
		rating
	};
	
	return myObj;
});

function greatherThan( obj ) {
	if( obj.rating >= 8 ) {
		return true;
	}else {
		return false;
	}
};

filteredList = filteredList.filter( greatherThan );

console.log( filteredList );
/*[{"title": "Inception","rating": "8.8"},{"title": "Interstellar","rating": "8.6"},
{"title": "The Dark Knight","rating": "9.0"},{"title": "Batman Begins","rating": "8.3"}]
*/

#6

hi - i’m wondering about your ES6 solution. the challenge is wanting the headings in quotes as well. How can we get title and rating in quotes? your soution returns:

[ { title: ‘Inception’, rating: ‘8.8’ },
{ title: ‘Interstellar’, rating: ‘8.6’ },
{ title: ‘The Dark Knight’, rating: ‘9.0’ },
{ title: ‘Batman Begins’, rating: ‘8.3’ } ]

filteredList should equal [{“title”: “Inception”,“rating”: “8.8”},{“title”: “Interstellar”,“rating”: “8.6”},{“title”: “The Dark Knight”,“rating”: “9.0”},{“title”: “Batman Begins”,“rating”: “8.3”}]


#7

My ES6 solution passes the tests, because it is not necessary to have the quotes for the property names, because they do not have spaces in them.

Even if you wrote the following, it will still not include the quotation marks in the final console.log statement.

const filteredList = watchList.filter((elem) => Number(elem.imdbRating) >= 8.0)
  .map((elem) => ({"title": elem.Title, "rating": elem.imdbRating}));

#8

This is my solution

var filteredList = watchList.map(function(x){
  return {title: x["Title"], rating: x["imdbRating"]}
}).filter(x => x.rating >= 8);

#9

Which one should be the first? .map() or .filter()


#10

This was my solutiong, scanning through the above it appears to be a combination of some of the above. It passes but not sure its ideal?

const filteredList = watchList.filter((item)=>{
return Number(item.imdbRating) >= 8.0;
}).map((item) =>{
return {title: item.Title,rating:item.imdbRating};
});

// Add your code above this line

console.log(filteredList);


#11

If you filter first, there are less elements for the map to have to iterate through.


#12

Your code has been blurred out to avoid spoiling a full working solution for other campers who may not yet want to see a complete solution. In the future, if you post a full passing solution to a challenge and have questions about it, please surround it with [spoiler] and [/spoiler] tags on the line above and below your solution code.

Thank you.


#13

I did something similar.

What I don’t understand is why the same code without the return statements inside of filter() and map() returns an empty array…

Or in other words, why are those return statements necessary?

It was my understanding that filter() should return an array of all the objects that pass the test. Same with map. So why does the test need to return the object?

Example:

// Why does this method require return statements?
let filteredList = watchList
                          .filter( obj => { return parseFloat(obj["imdbRating"]) >= 8.0; })
                          .map( obj => { return {title: obj["Title"], rating: obj["imdbRating"]}; });

// Better way
let filteredList = watchList.filter( obj =>  parseFloat(obj["imdbRating"]) >= 8.0 )
                            .map( obj => ({title: obj["Title"], rating: obj["imdbRating"]}) );


#14

“the test” as you refer to it is actually a function. Filter and Map both require functions (referred to as callbacks) to be passed into them. The function must return a true/false value in the case of filter.
Review the filter documentation here for a complete explanation:


#15

Because that’s how filter and map methods work as array prototypes. Somewhere in FCC exercises (Can’t remember them top of my head), you get to actually write these methods on your own and you will stand why return statements were used.

In a nutshell, I think these methods were designed in a way that they are running through forloops with callbacks so when a condition is met it pushes the value to an empty array.


#16

Can you please explain why you are allowed to construct your object without putting title and rating in quotes? I can remember trying to construct objects and running into a problem with that.


#17

Can you post the code you are asking about?


#18

#19

// Add your code below this line

let rating = watchList.map(obj =>{

return {“title”: obj.Title, “rating”: obj.imdbRating};
});

// Add your code above this line

console.log(rating);

This is my passed solution. But the output below on my console had a little different, I still try to figure out or someone can teach me.

[[object Object] {
rating: “8.8”,
title: “Inception”
}, [object Object] {
rating: “8.6”,
title: “Interstellar”
}, [object Object] {
rating: “9.0”,
title: “The Dark Knight”
}, [object Object] {
rating: “8.3”,
title: “Batman Begins”
}, [object Object] {
rating: “7.9”,
title: “Avatar”
}]


#22

In your list you have film with rating < 8.0 (7.9).
Use filter for that.