Home > database >  Simplify nested loops function in Javascript
Simplify nested loops function in Javascript

Time:08-24

I have two arrays of data, one containing a list of movies and one various movie genres. I want to create a new array combining the data of those two. I need to match the genre_ids of the first one with the ids of the second. The new array will have all the information the movies array already have plus a new field containing the genre names (from the second array). I have managed to do it but I guess there is a better and less complex way. Any suggestions on how to achieve that?

Initial arrays

const movies = [
 {
   genre_ids: [1, 2, 3],
   id: 1,
   title: 'Title One',
 },
 {
   genre_ids: [1, 3, 5],
   id: 2,
   title: 'Title Two',
 },
 {
   genre_ids: [3, 4, 5],
   id: 3,
   title: 'Title Three',
 },
];

const moviesGenres = [
 {
   id: 1,
   name: 'Comedy',
 },
 {
   id: 2,
   name: 'Action',
 },
 {
   id: 3,
   name: 'Horror',
 },
 {
   id: 4,
   name: 'Fantasy',
 },
 {
   id: 5,
   name: 'Western',
 },
];

Result array

const newMoviesArray = [
  {
    genre_ids: [1, 2, 3],
    genre: ['Comedy', 'Action', 'Horror'],
    id: 1,
    title: 'Title One',
  },
  {
    genre_ids: [1, 3, 5],
    genre: ['Comedy', 'Horror', 'Western'],
    id: 2,
    title: 'Title Two',
  },
  {
    genre_ids: [3, 4, 5],
    genre: ['Horror', 'Fantasy', 'Western'],
    id: 3,
    title: 'Title Three',
  },
];

Current implementation

const getMoviesWithGenres = (movies, movieGenres) => {
  const newMoviesArray = JSON.parse(JSON.stringify(movies));
  for (const movie of moviesCopy) {
    const movieGenreIds = movie.genre_ids;
    const genreItems = [];
    for (const genreId of movieGenreIds) {
      for (const genre of movieGenres) {
        if (genre.id === genreId) {
          genreItems.push(genre.name);
        }
      }
    }
    movie.genres = genreItems;
  }
  return newMoviesArray;
};

CodePudding user response:

You can make use of array.map() to map over the movies and array.filter() to filter over moviesGenres along with array.indexOf which searches for the match id's index and then you could get the names of matching genre by map method and merge it to the original movie like {...movie, genre} .

Working Example:

const movies = [
 {
   genre_ids: [1, 2, 3],
   id: 1,
   title: 'Title One',
 },
 {
   genre_ids: [1, 3, 5],
   id: 2,
   title: 'Title Two',
 },
 {
   genre_ids: [3, 4, 5],
   id: 3,
   title: 'Title Three',
 },
];

const moviesGenres = [
 {
   id: 1,
   name: 'Comedy',
 },
 {
   id: 2,
   name: 'Action',
 },
 {
   id: 3,
   name: 'Horror',
 },
 {
   id: 4,
   name: 'Fantasy',
 },
 {
   id: 5,
   name: 'Western',
 },
];

const newMoviesArray = movies.map((movie, index) => {
  const matchedGeneres = moviesGenres.filter(({id, name}) => movie.genre_ids.indexOf(id) !== -1);
  const genre = matchedGeneres.map(({name}) => name);
  return {...movie, genre}
});

console.log(newMoviesArray);

  • Related