skip to Main Content

I have big json with movies. This json have 2 arrays "genres" and "movies". Part of json looks like this:

{
    "genres": [
        "Comedy",
        "Fantasy",
        "Crime",
        "Drama",
        "Music",
        "Adventure",
        "History",
        "Thriller",
        "Animation",
    ],
    "movies": [
        {
            "id": 1,
            "title": "Beetlejuice",
            "year": "1988",
            "runtime": "92",
            "genres": [
                "Comedy",
                "Fantasy"
            ],
            "director": "Tim Burton",
            "actors": "Alec Baldwin, Geena Davis, Annie McEnroe, Maurice Page",
            "plot": "A couple of recently deceased ghosts contract the services of a "bio-exorcist" in order to remove the obnoxious new owners of their house.",
            "posterUrl": "https://m.media-amazon.com/images/M/MV5BZDdmNjBlYTctNWU0MC00ODQxLWEzNDQtZGY1NmRhYjNmNDczXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_FMjpg_UX1000_.jpg"
        },
        {
            "id": 2,
            "title": "The Cotton Club",
            "year": "1984",
            "runtime": "127",
            "genres": [
                "Crime",
                "Drama",
                "Music"
            ],
            "director": "Francis Ford Coppola",
            "actors": "Richard Gere, Gregory Hines, Diane Lane, Lonette McKee",
            "plot": "The Cotton Club was a famous night club in Harlem. The story follows the people that visited the club, those that ran it, and is peppered with the Jazz music that made it so famous.",
            "posterUrl": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTU5ODAyNzA4OV5BMl5BanBnXkFtZTcwNzYwNTIzNA@@._V1_SX300.jpg"
        },
        {
            "id": 3,
            "title": "The Shawshank Redemption",
            "year": "1994",
            "runtime": "142",
            "genres": [
                "Crime",
                "Drama"
            ],
            "director": "Frank Darabont",
            "actors": "Tim Robbins, Morgan Freeman, Bob Gunton, William Sadler",
            "plot": "Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common decency.",
            "posterUrl": "https://m.media-amazon.com/images/M/MV5BMTQ1ODM2MjY3OV5BMl5BanBnXkFtZTgwMTU2MjEyMDE@._V1_.jpg"
        },

and other 143 movies…

I need to find how many genres have all movies using "genres" array in "movies" array.

I made this code:

const comedy = props.movies.map(movie => movie.genres.filter(genre => genre === "Comedy").length)
        .reduce((total, count) => total + count, 0);
    
const fantasy = props.movies.map(movie => movie.genres.filter(genre => genre === "Fantasy").length)
        .reduce((total, count) => total + count, 0);
    
const crime = props.movies.map(movie => movie.genres.filter(genre => genre === "Crime").length)
        .reduce((total, count) => total + count, 0);

and I made it for other 18 genres.

Can I do this code shorter? Thnx

2

Answers


  1. Fairly simply, as you have the list of genres in the same object:

    const all = Object.fromEntries(
        props.genres.map(genre => 
         [
           genre, 
           props.movies.map(
               movie => movie.genres.filter(filmGenre => filmGenre === genre).length
           ).reduce((total, count) => total + count, 0)
         ]
        )
      );
    

    This will result in something like

    {
      "comedy": 42,
      "action": 0
    }
    
    
    

    For reference, fromEntries: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries

    See below example (I’ve removed the extra unused properties from the movies for readability)

    const props = {
      "genres": [
        "Comedy",
        "Fantasy",
        "Crime",
        "Drama",
        "Music",
      ],
      "movies": [{
          "title": "Beetlejuice",
          "genres": [
            "Comedy",
            "Fantasy"
          ],
        },
        {
          "title": "The Cotton Club",
          "genres": [
            "Crime",
            "Drama",
            "Music"
          ],
        },
        {
          "title": "The Shawshank Redemption",
          "genres": [
            "Crime",
            "Drama"
          ],
        }
      ]
    };
    const all = Object.fromEntries(
      props.genres.map(genre => [
        genre,
        props.movies.map(
          movie => movie.genres.filter(filmGenre => filmGenre === genre).length
        ).reduce((total, count) => total + count, 0)
      ])
    );
    console.log(all);
    Login or Signup to reply.
  2. Here is a solution iterating over the movies only once (this solution works provided that a movie doesn’t declare duplicate genre in its genres array)

    const createInitValue = () => Object.fromEntries(
      props.genres.map(genre => [genre, 0])
    );
    
    const nbMoviesByGenre = props.movies
      .flatMap(movie => movie.genres)
      .reduce((res, genre) => {
        if (!isNaN(res[genre])) {
          res[genre]++;
        }
        return res;
      }, createInitValue());
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search