TMDB API returns an array of movie objects that look like this:
{
"vote_count": 1527,
"id": 338952,
"video": false,
"vote_average": 7,
"title": "Fantastic Beasts: The Crimes of Grindelwald",
"popularity": 272.487,
"poster_path": "/uyJgTzAsp3Za2TaPiZt2yaKYRIR.jpg",
"original_language": "en",
"original_title": "Fantastic Beasts: The Crimes of Grindelwald",
"genre_ids": [
10751,
14,
12
],
"backdrop_path": "/xgbeBCjmFpRYHDF7tQ7U98EREWp.jpg",
"adult": false,
"overview": "Gellert Grindelwald has .....",
"release_date": "2018-11-14"
}
They also provide an API to return ALL available genres in an array of objects with a key and a label:
genres": [
{
"id": 28,
"name": "Action"
},
{
"id": 12,
"name": "Adventure"
},
{
"id": 16,
"name": "Animation"
}
]
What I need to do is get a list of all unique genres from the now playing API with their label values.
So my question isn't so much about how to do this, but what is the cleanest and most efficient approach.
My attempt:
let uniqueIds = new Set(), genres;
// First get all available unique genre IDs from the now playing list
for(var i = 0; i < this.state.items.length; i++){
for(var x = 0; x < this.movies[i].genre_ids.length; x++){
uniqueIds.add(this.movies[i].genre_ids[x])
}
}
// build array of genre objects from unique genre IDs
genres = this.genres.filter((genre) => uniqueIds.has(genre.id));
asked Nov 30, 2018 at 14:01
1 Answer 1
1) For each object in the array grab the genre_ids
2) filter
out the genre objects that have an id included in the ids array.
const api = [{"vote_count":1527,"id":338952,"video":false,"vote_average":7,"title":"Fantastic Beasts: The Crimes of Grindelwald","popularity":272.487,"poster_path":"/uyJgTzAsp3Za2TaPiZt2yaKYRIR.jpg","original_language":"en","original_title":"Fantastic Beasts: The Crimes of Grindelwald","genre_ids":[10751,14,12],"backdrop_path":"/xgbeBCjmFpRYHDF7tQ7U98EREWp.jpg","adult":false,"overview":"Gellert Grindelwald has .....","release_date":"2018-11-14"},{"vote_count":1527,"id":338952,"video":false,"vote_average":7,"title":"Fantastic Beasts: The Crimes of Grindelwald","popularity":272.487,"poster_path":"/uyJgTzAsp3Za2TaPiZt2yaKYRIR.jpg","original_language":"en","original_title":"Fantastic Beasts: The Crimes of Grindelwald","genre_ids":[10751,14,16],"backdrop_path":"/xgbeBCjmFpRYHDF7tQ7U98EREWp.jpg","adult":false,"overview":"Gellert Grindelwald has .....","release_date":"2018-11-14"}];
const genres = [{"id":28,"name":"Action"},{"id":12,"name":"Adventure"},{"id":16,"name":"Animation"}];
// [].concat(...arr) flattens consequtive arrays down
const idArr = [].concat(...api.map(obj => obj.genre_ids));
const matchingGenres = genres.filter(obj => idArr.includes(obj.id));
console.log(matchingGenres);
answered Nov 30, 2018 at 14:19
Sign up to request clarification or add additional context in comments.
6 Comments
shanahobo86
Ah... very nice. this is destructuring? it's much neater and doesn't have that awful nested loop.
Andy
I updated the answer to account for the array of objects, rather than one object.
Robbie Milejczak
@shanahobo86 it's not destructuring, what's happening here is called spreading developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… you can read about destructuring here developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Andy
@RobbieMilejczak, FYI the very first edit of this answer did contain destructuring. It's that the OP was referring to. But, yes, this edit does contain the spread syntax.
James
filter out the genre objects that don't have an id included
|
lang-js