0

I'm going through Codecademy's Javascript - Intro to Objects course, and am currently hung up on the the "4. I have to celebrate you baby" exercise in the "Review: The story so far..." lesson.

The exercise is:

This exercise has lots of movies and reviews to type in. You might wonder, "Is this teaching coding or typing?!"

But there's a reason why there are so many cases to deal with. We want to show that if we used if-else statements, it would be inefficient. What alternative from the conditionals lesson can we use?

Imagine you have a movie collection and you want to write some code that assigns your review to each of them. Obviously each review differs depending on the movie. Below are the movies and your review. Use a structure learned in an earlier lesson to write code for the information below:

  • "Matrix" - "good trip out"
  • "Princess Bride" - "awesome date night movie"
  • "Welcome to America" - "Amjad's favorite"
  • "Remember the Titans" - "love the sports"
  • "Why do I look like I'm 12?" - "The Ryan and Zach story"
  • "Fighting Kangaroos in the wild" - "Token Australian movie for Leng"

getReview should be a function that takes a movie name and returns its review based on the information above. If given a movie name not found just return "I don't know!".

My understanding is that it is important to separate data from logic. So, my initial solution was:

var getReview = function (movie) {
    for (var i = 0; i < movieReviews.length; i++) {
        if (movie === movieReviews[i].name) {
            return(movieReviews[i].review);
        }
    }
    return("I don't know!");
};

var movieReviews = [{name: "Matrix", review:"good trip out"},
    {name: "Princess Bride", review:"awesome date night movie"},
    {name: "Welcome to America", review:"Amjad's favorite"},
    {name: "Remember the Titans", review:"love the sports"},
    {name: "Why do I look like I'm 12?", review:"The Ryan and Zach story"},
    {name: "Fighting Kangaroos in the wild", review:"Token Australian movie for Leng"}];

console.log(getReview("Matrix"));

I'm sure there are ways to optimize this, but overall I think it would be easier to add, edit, modify, etc. the movieReviews array than it would be to program switch statements.

In otherwords, I'm not seeing why a switch statement would be inefficient in comparison to an if-else statement. What am I missing?

EDIT: The help text for the problem is:

It is possible to use if, else if and else statements, but that is inefficient. In situations where you have lots of different scenarios and different comes, try using a switch statement!

Because we are defining a function, we can make use of the return keyword!

Make sure that what you return matches the case of the review text

7
  • 3
    I don't really understand you're question .. you don't seem to be using a switch Commented Feb 12, 2013 at 4:48
  • The point of the exercise isn't to use a switch statement. It is asking, is there a better way. Your method getReview is a good first step towards it. Instead of writing something like: if (movie == "Matrix") // Do something else if (movie == "Princess Bride") // Do something else // .... You are looping through an Array to find the answer. Way less code than the poor if/else if approach I wrote above. Now, is there a better way to find the names rather than an Array? Commented Feb 12, 2013 at 4:53
  • @RobDiMarco Marco - I'm sure there are more optimal ways of finding the names (I'm not sure what they are at the moment, but I'm sure they exist ;-) . I'm just failing to see how a switch statement is better than an if/then for the given scenario. Commented Feb 12, 2013 at 4:58
  • @ExplosionPills - When I submit the solution above, the Codecademy terminal gives me Oops, try again. Better use a switch statement. When I view the exercise 'help text' it tells me that if/else statements are inefficient and that I should be using a switch statement. (Added the 'help text' to my main question.) But I don't see why a switch would be more optimal than an if/else in this case. Commented Feb 12, 2013 at 5:02
  • Well, if it's any consolation your solution looks good to me. Maybe you should write CodeAcademy about it. In the meantime you could always just change your if to switch Commented Feb 12, 2013 at 5:03

3 Answers 3

2

Really, the question as it stands is flawed. The course you're taking is an Introduction to Objects, so why both with arrays that aren't associative? Simply:

movieReviews = { 
  "matrix": "a good trip"
}
// These are now both valid for accessing "a good trip"
movieReviews["matrix"];
movieReviews.matrix

Every movie is going to have a unique name, which makes it a perfect candidate for a key. Furthermore, the function used for searching for reviews should be a method of the review object. For what it's worth (and hopefully it's something, even if not right now), this is how I would implement the solution.

MovieReviews = function() {
  /* Private data. */
  var data = {
    "matrix": "good trip out",
    "Princess Bride": "awesome date night movie",
    "Welcome to America": "Amjad's favorite"
  }
  /* Get a review for a movie by name, or notify that we don't know */
  this.getReview = function(movie) {
    if(data.hasOwnProperty(movie)) { return data[movie]; }
    return "I don't know!";
  }
  /* Add a review by movie name, and review string. */
  this.addReview = function(movie, review) {
    data[movie] = review;
  }
}

Now instantiate a new MovieReview object, add a new movie review, and print some tests.

var reviews = new MovieReviews();
reviews.addReview("Remember the Titans", "love the sports");

console.log(reviews.getReview("matrix")); // 'good trip out'
console.log(reviews.getReview("Remember the Titans")); // 'love the sports'
console.log(reviews.getReview("A Scanner Darkly")); // 'I don't know!'

This way accessing your reviews for each movie is trivial, and requires no iteration at all. You are also containing your data within an object, providing encapsulation and forcing users to use your interfaces.

As for your original question, it's hard for me to say whether and if-else or switch statement would be more efficient without performing some timed tests (maybe something you could do and let us know!). But based on what's written here,

"If multiple cases match the provided value, the first case that matches is selected..."

this seems like it's just iterating through the cases anyway. How the JavaScript control structures are translated with your current JS engine probably optimises your switch statement, and I would bet that it performs better over if-else with a large quantities of options.

Performance aside, it's much nice reading a switch statement that has many elements, compared to an if-else. Also, there are often time when you can change other factors like your object types (array -> object in my example), to better fix an issue.

Don't get caught in the trap of prematurely optimising your code, or else you'll never get anything finished and people that maintain your work will hate you, forever, and ever.

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

4 Comments

Thank you! I figured there was some way to use the movie names as keys, but hadn't been able to work out the syntax. It looks like the end of your post got cut off. Were you going to say more on encapsulation? From the lesson's point of view, is there any performance benefits of switch statements over if/then statements?
@RecursiveSelfOptimization - Yeah sorry, forgot to finish! Added a bit at the end about performace benefits.
Thank you for such a complete answer that not only addressed my primary question but also provided an understandable walk-through to a more optimal option. RE: "Don't get caught in the trap of prematurely optimising your code, or else you'll never get anything finished ..." Have we met before? RE: "...performing some timed tests (maybe something you could do..." I'm not there yet, but it's on my todo list.
@RecursiveSelfOptimization - No problems! Glad to head it helped!
0

You're storing everything in an array, running loops when you could just use case/switch. You could complete this task in numerous different ways, but you'll use less characters if you use a case/switch as opposed to a massive amount of conditionals.

function movieReviews(movie) {
var x = "No review.";
switch (movie)
{
case 'Matrix':
  x="good trip out";
  break;
case 'Princess Bride':
  x="awesome date night movie";
  break;
case 'Remember the Titans':
  x="love the sports";
  break;
case 'Welcome to America':
  x="Amjad's favorite";
  break;
default:
  x="No movie selected.";
}
document.write("Movie: " + movie + " Review: " + x);
}

It makes for cleaner code too.

3 Comments

Is there some performance problem with a loop? Specifically, if Matrix is the first entry in either the array or the switch statement, then it is compared to a conditional, the review value is set, and the if/then or switch is terminated. So is there some processing overhead associated with loops that isn't present in switch statements? And is the character count really that much of an overhead? And as for "cleaner code", the array looks cleaner to my eyes; not to mention it isn't broken up by all the "cases", "break"s, and new lines. But maybe that's just novice eyes.
It's a matter of size. Your array is holding all of the movies and reviews. My switch/case is only assigning a value to a variable once a condition is met. Your loop is checking length, values of different parts of the array. My case/switch is doing none of that. Will this be a performance issue for a small scale operation? No. It is client-side, but if you had a large application of say 10,000 lines of code, that little boost in performance each time makes a huge difference.
Thank you for providing some distinct performance advantages of the switch over the if/than! I think Aesthete provided a more thorough answer, so I gave him the correct mark. If I ever get enough points to vote your answer up I will, because it was still helpful.
0

Try the following:

var getReview = function (movie) {
    switch (movie) {
        case 'Matrix': return "good trip out";
        break;
        case 'Princess Bride': return "awesome date night movie";
        break;
        case 'Welcome to America': return "Amjad's favorite";
        break;
        case 'Remember the Titans': return "love the sports";
        break;
        case 'Why do I look like I\'m 12?': return "The Ryan and Zach Story";
        break;
        case "Fighting Kangaroos in the wild": return "TOken Australian movie for Leng";
        break;
        default: return "I don't know!"
        break;
    }
};

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.