0

I am trying to figure out the best way to map an objects id property that is within a multi-dimension array to object values that are within another array that share the same id.

As an example i have an array of genre_ids like so:

0: {id: 1, name: 'sci-fi'},
1: {id: 2, name 'comedy'},
2: {id: 3, name: 'action'}

And an array of tv_show_genre_ids which looks like:

0: {name: ..., genre_ids: [1, 4, 9]},
1: {name: ..., genre_ids: [2, 3, 4]},

I was trying to figure out the best way to retrieve a list of the genres name by its id.

I have managed to create a working solution so far but it feels incredibly dirty as i am performing multiple nested loops and i wasn't sure if there is a cleaner more declarative approach to my solution

Here is my approach which assumes i already have a list of genre ids and names (accessed within this.genres.

this.http.get('https://api.com/shows')
    .subscribe((res: array <any> ) => {
        this.shows = res.results;
        this.shows.forEach(show => {
            show.genre_names = '';
            show.genre_ids.forEach(id => {
                for (const [i, v] of this.genres.entries()) {
                    if (id == v.id) {
                        if (this.genres[i] && this.genres[i].name) {
                            if (show.genre_names === '') {
                                show.genre_names = this.genres[i].name
                            } else {
                                show.genre_names += `, ${this.genres[i].name}`;
                            }
                        }
                    }
                }
            })
        });
    });

Is there a better way of doing this as i seem to come across this type of problem quite often when trying to map ids from one object to another within multi-dimension arrays.

Any guidance would be greatly appreciated.

EDIT:

Here is an example of the Genre Data from the API af:

 0: {id: 10759, name: "Action & Adventure"}
 1: {id: 16, name: "Animation"}

And here is an example of the show data from the API:

0:
backdrop_path: "/ok1YiumqOCYzUmuTktnupOQOvV5.jpg"
first_air_date: "2004-05-10"
genre_ids: (2) [16, 35]
id: 100
name: "I Am Not an Animal"
origin_country: ["GB"]
original_language: "en"
original_name: "I Am Not an Animal"
overview: "I Am Not An Animal is an animated comedy series about the only six talking animals in the world, whose cosseted existence in a vivisection unit is turned upside down when they are liberated by animal rights activists."
popularity: 10.709
poster_path: "/nMhv6jG5dtLdW7rgguYWvpbk0YN.jpg"
vote_average: 9.5
vote_count: 341 

I want to add a new property to the show object named genre_names which gets the genre name via the genre response.

4
  • Given the two inputs "genre_ids" and "tv_show_genre_ids", what is the expected output? I think this will help understand the problem better. Commented Sep 30, 2019 at 23:00
  • Well every show object has a property which contains an array of genre ids. I want each of the values within that array to map to the value in the genre list array that i already have and then add a new property to each individual show with all of the genre names that are applicable to it. If that makes sense? You can see the new property that i have created 'show.genre_names'. I would like this to contain all of the genre names but i need to get the name of the genre by its ID which is in another array. Commented Sep 30, 2019 at 23:03
  • I mean, can you give the actual output? Not the the explanation. What will it be like if you console log the output, for a sample input? Commented Sep 30, 2019 at 23:09
  • I have made an edit to the original post. I hope this is what you was asking for in regards to the input. Sorry if i misunderstood your question. Commented Sep 30, 2019 at 23:19

1 Answer 1

1

Your best bet is to first convert your genres into a Map or an object to use as a lookup:

const genreLookup = new Map();
this.genres.forEach(genre => genreLookup.set(genre.id, genre));

Now when you process an array of shows, you don't have to loop through the genres multiple times:

this.shows.forEach(show => {
  show.genre_names = show.genre_ids
    .filter(id => genreLookup.has(id))
    .map(id => genreLookup.get(id).name)
    .join(', ');
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, that seems significantly cleaner :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.