2

I am sorry this is so long, but I am stuck and trying to figure out why I am not getting a value.

This function should return the number of movies in which all the actors that were given as an argument perform in it.

For example: findNumOfMoviesByActors(["Morgan Freeman", "Bob Gunton"]) should return 1, because there is only one movie that both are in (see array below).

it is a big array of movies but this is a snipit:

const movies = [
  {"title": "Beetlejuice",
    "actors": "Alec Baldwin, Geena Davis, Annie McEnroe, Maurice Page"},

  {"title": "The Cotton Club",
    "actors": "Richard Gere, Gregory Hines, Diane Lane, Lonette McKee"},

  {"title": "The Shawshank Redemption",
   "actors": "Tim Robbins, Morgan Freeman, Bob Gunton, William Sadler"},

  {"title": "Crocodile Dundee",
   "actors": "Paul Hogan, Linda Kozlowski, John Meillon, David Gulpilil"}]
 

This is my code so far:

const findNumOfMoviesByActors = actors => {
      for (i = 0; i < movies.length; i++) {
            movies[i].actors = movies[i].actors.split(' ')
        }
    
      for (i = 0; i < movies.length; i++) {
          let count = 0
          if (actors === movies[i].actors) {
              count++
          }
          return count
      }
  }
    
    const actorCheck = ["Paul Hogan", "Linda Kozlowski"]
    let test = findNumOfMoviesByActors(actorCheck)
    console.log(test)
1
  • need to split with comma and trim because comma is part of the string now. Commented Jun 21, 2020 at 9:12

5 Answers 5

5

You need to split the string with possible whitespace, because you get for the second actor of a movie a leading space and then you need to iterate either the wanted actors or the given actors and count the occurences of a movie.

If a movie contains all wanted actors increment the movie count.

const
    findNumOfMoviesByActors = actors => {
        let movieCount = 0;
        for (let i = 0; i < movies.length; i++) {
            let count = 0;
            for (const actor of movies[i].actors.split(/,\s*/)) {
                if (actors.includes(actor)) count++;
                if (count === actors.length) {
                    movieCount++;
                    break;
                }
            }                
        }
        return movieCount;
    },
    movies = [{ title: "Beetlejuice", actors: "Alec Baldwin, Geena Davis, Annie McEnroe, Maurice Page" }, { title: "The Cotton Club", actors: "Richard Gere, Gregory Hines, Diane Lane, Lonette McKee" },  { title: "The Shawshank Redemption", actors: "Tim Robbins, Morgan Freeman, Bob Gunton, William Sadler" },  { title: "Crocodile Dundee", actors: "Paul Hogan, Linda Kozlowski, John Meillon, David Gulpilil" }],
    actorCheck = ["Paul Hogan", "Linda Kozlowski"];
    
let test = findNumOfMoviesByActors(actorCheck);
console.log(test)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! This is super clear and very very helpful
0
movies.filter((m) => m.actors.contains("Morgan Freeman, Bob Gunton")).length

5 Comments

I'm sorry, I am going into my second week of learning JS, what you just wrote does not make sense to me. I will try to figure it out. Thank you for answering
btw, it works only if the the string is in the the actors property. if the names are switched, it soed not work.
@NinaScholz - I agree.
you probably want .includes() rather than .contains()
While this code may resolve the OP's issue, it is best to include an explanation as to how your code addresses the OP's issue. In this way, future visitors can learn from your post, and apply it to their own code. SO is not a coding service, but a resource for knowledge. Also, high quality, complete answers are more likely to be upvoted. These features, along with the requirement that all posts are self-contained, are some of the strengths of SO as a platform, that differentiates it from forums. You can edit to add additional info &/or to supplement your explanations with source documentation.
0

Here's two ways I found of solving it:

The first uses a functional style and so doesn't involve writing any loops by hand. It does take some time to wrap your head around if you're just learning Javascript, but once you understand the process you can apply this style to just about any type of problem. It's worth learning and will make writing JS apps a lot easier in the long run. You just have to be careful about using the sort() method because it modifies the original arrays - so make sure to copy them first:

const movies = [
    {"title": "Beetlejuice",
      "actors": "Alec Baldwin, Geena Davis, Annie McEnroe, Maurice Page"},
  
    {"title": "The Cotton Club",
      "actors": "Richard Gere, Gregory Hines, Diane Lane, Lonette McKee"},
  
    {"title": "The Shawshank Redemption",
     "actors": "Tim Robbins, Morgan Freeman, Bob Gunton, William Sadler"},
  
    {"title": "Crocodile Dundee",
     "actors": "Paul Hogan, Linda Kozlowski, John Meillon, David Gulpilil"}
    
]

const countMoviesFunctional = (arr) => {
    const moviesCopy = [...movies];
    const arrCopy = [...arr];
    return moviesCopy.map(movie => movie.actors.split(", ").sort().join("|")).filter(actorStr => actorStr.includes(arrCopy.sort().join("|"))).length;
}

console.log(countMoviesFunctional(["Paul Hogan", "Linda Kozlowski"]))

The second way uses an imperative style and is close to what you were trying to do in the first place. While it's easier to understand as a beginner, writing loops all over the place gets confusing and often leads to lots of errors. It also makes your code a whole lot more verbose which can be hard to debug. Best to try and write more functional code to avoid these problems. But here is the code nonetheless:

const movies = [
    {"title": "Beetlejuice",
      "actors": "Alec Baldwin, Geena Davis, Annie McEnroe, Maurice Page"},
  
    {"title": "The Cotton Club",
      "actors": "Richard Gere, Gregory Hines, Diane Lane, Lonette McKee"},
  
    {"title": "The Shawshank Redemption",
     "actors": "Tim Robbins, Morgan Freeman, Bob Gunton, William Sadler"},
  
    {"title": "Crocodile Dundee",
     "actors": "Paul Hogan, Linda Kozlowski, John Meillon, David Gulpilil"}
    
]

const filterMoviesImperative = (arr) => {
    let count = 0;
    for(let i=0; i<movies.length; i++) {
        let containsAll = true;
        const actorsArr = movies[i].actors.split(", ");
        for(let j=0; j<arr.length; j++) {
            if(!actorsArr.includes(arr[j])) {
                containsAll = false;
                break;
            }
        }

        if(containsAll) count++;
    }

    return count;
}

console.log(filterMoviesImperative(["Paul Hogan", "Linda Kozlowski"]));

Comments

0

You need to split by ',' and then trim. The comparison is easy enough: take all actors given and check if they exist in movie, if they do then add one to the counter. You can even create an array of movie titles and also return that. I changed the actors in the movies array so you can have a working example

var movies = [
  {"title": "Beetlejuice",
    "actors": "Tim Robbins, Morgan Freeman, Annie McEnroe, Maurice Page"},

  {"title": "The Cotton Club",
    "actors": "Tim Robbins, Morgan Freeman, Diane Lane, Lonette McKee"},

  {"title": "The Shawshank Redemption",
   "actors": "Tim Robbins, Morgan Freeman, Bob Gunton, William Sadler"},

  {"title": "Crocodile Dundee",
   "actors": "Paul Hogan, Linda Kozlowski, John Meillon, David Gulpilil"}]

function findNumOfMoviesByActors(actors) {
  for (i = 0; i < movies.length; i++) {
    movies[i].actors = movies[i].actors.split(',');
    for (j = 0; j < movies[i].actors.length; j++) {
      movies[i].actors[j] = movies[i].actors[j].trim();
    }
  }
  
  var res = [];
  var count = 0;
  for (i = 0; i < movies.length; i++) {
    var all = 0;
    for (var actor of movies[i].actors) {
      if (actors.includes(actor)) all++;
        if(all === actors.length) {
          count++;
          res.push(movies[i].title);
          break;
        }
      } 
    }
    return [res, count];
}

var actorCheck = ["Tim Robbins", "Morgan Freeman"];
var test = findNumOfMoviesByActors(actorCheck);
console.log(test);

Comments

0

You can either use filter() or reduce() operators from ES6 to get your desired output. A possible approach is given below

const movies = [{
    "title": "Beetlejuice",
    "actors": "Alec Baldwin, Geena Davis, Annie McEnroe, Maurice Page"
  },

  {
    "title": "The Cotton Club",
    "actors": "Richard Gere, Gregory Hines, Diane Lane, Lonette McKee"
  },

  {
    "title": "The Shawshank Redemption",
    "actors": "Tim Robbins, Morgan Freeman, Bob Gunton, William Sadler"
  },

  {
    "title": "Crocodile Dundee",
    "actors": "Paul Hogan, Linda Kozlowski, John Meillon, David Gulpilil"
  }
];

const findNumOfMoviesByActors = actors => {
  return movies.reduce((acc, movie) =>
    acc + ((actors.every(a =>
      movie.actors.split(/,\s*/g).includes(a)) && 1) || 0), 0)
};


console.log(findNumOfMoviesByActors(["Morgan Freeman", "Bob Gunton"]));

Comments

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.