views:

290

answers:

5
for( count = 1 ; count < 6 ; count++ ) {
switch (count)
    {
    case (2):   document.write("hi"); break;     
    case (count > 3):   document.write("bye"); break;    
    case (count >= 4): document.write("lol"); break;
}
}

Because it's not working the way I expect, not printing bye and lol, it makes me think this is invalid in JavaScript. I tried looking for some examples to see if people do this on Google, and I saw none. So is this valid or not? or Why might this not work?

+9  A: 

When switch is interpreted, the expression in the parentheses is compared to values of the particular cases.

So in your case the value of count would be compared to the values of 2, count > 3 and count >= 4. And that won’t work. Although you can rewrite it and compare to true to get it working:

switch (true) {
    case (count == 2):
        document.write("hi");
        break;
    case (count > 3):
        document.write("bye");
        break;
    case (count >= 4):
        document.write("lol");
        break;
}

But that’s not how switch is supposed to be used.

Use if statements instead:

if (count == 2) {
    document.write("hi");
} else if (count > 3) {
    document.write("bye");
} else if (count >= 4) {
    document.write("lol");
}

Edit    Since you use the switch cases exclusively (break if a case matches), my switch-to-if/else translation is correct.

But the count >= 4 case/branch will never be applied since count > 3 is true (also) for count values greater or equal 4.

To fix this problem (write “bye” and “lol” for values greater or equal 4), remove the last else to make the last if statement independent from the preceding:

if (count == 2) {
    document.write("hi");
} else if (count > 3) {
    document.write("bye");
}
if (count >= 4) {
    document.write("lol");
}
Gumbo
@Doug - the `if ( count >= 4 )` expression will never evaluate to true in this context. Not sure why it's there.
Peter Bailey
@Doug: Remove the last `else` at it will.
Gumbo
There are still problems with order of evaluation in both the switch and if statements. See my comment below: http://stackoverflow.com/questions/2312817/javascript-switch-with-logical-operators/3282442#3282442
Dan Breslau
A: 

You should swap your last two cases.

brian
This is not enough to make it work
anthares
Why? Explain please.
Doug
@ anthares: not enough to get it to work, but it is a bug that will prevent it from working the way he is expecting.
brian
See my answer, you cannot put boolean expressions in the case statement ... it will not be evaluated how you expect. It will be compared to the count variable.@user210118 even swapping the last two cases will prevent from working the way OP is expecting.
anthares
@doug: > 3 will catch cases that should fall into >= 4.
brian
@anthares: you're missing the point. yes, we realize that the code was broken the way he had it but once he has addressed that issue (in a manner outlined by you and others), he needs to swap his last two case statements as 'lol' will never be output the way it sits now.
brian
And even when he swap then .. it still won't work... I now this case in unreachable, but what is the point of correcting wrong code with another wrong code ... Your answer is not a solution.
anthares
+1  A: 

You use the case clause in the wrong way. You should provide a value that will be compared to the value in the switch clause ... and not a boolean expression like this count>2

In this case this boolean expression will be cast to true or false (1 or 0) and compared to your value count and sometimes may work, sometimes - not.

You should consider replacing it with if statements.

anthares
A: 

The switch normally needs a fixed condition/value; because your count variable changes every time, it goes against that. Use if-else condition instead.

Sarfraz
A: 

This is a correction to Gumbo's answer. I'm writing a separate answer only because this won't fit as a comment.

Edit: Gumbo suggested in a comment that I may have misread Doug's intention. If the OP really wants both "bye" and "lol" to be printed out for count >= 4, then we need to remove a break from the switch. The cases are now back in the original order, so that "bye" and "lol" are printed in that order (which is apparently the OP's intent.)

switch (true) {
    case (count == 2):
        document.write("hi");
        break;
    case (count > 3):
        document.write("bye");
        // No break here; just fall through.
    case (count >= 4):
        document.write("lol");
        break;
}

In this case, I agree with Gumbo that the revised if statement is correct.

Original answer follows (assumes that the OP really wanted either "lol" or "bye" to print, but not both.)

The switch statement that Gumbo wrote won't work for count >= 4, for much the same reason that Gumbo's original if statement won't work: Because the cases are evaluated in sequence, count >= 4 implies that the second case (count > 3) will be executed; so the script will never reach the test for count >= 4. To fix this, the tests should be executed in the reverse order, from highest to lowest:

switch (true) {
    case (count >= 4):
        document.write("lol");
        break;
    case (count > 3):
        document.write("bye");
        break;
    case (count == 2):
        document.write("hi");
        break;
}

The corrected if statement is still not right either, because for count >= 4 it will produce both bye and lol on the output. Again, the tests within the if ladder should be arranged to go from highest to lowest values:

if (count >= 4) {
    document.write("lol");
} else if (count > 3) {
    document.write("bye"); 
} else if (count == 2) {
    document.write("hi");
}

This isn't an ideal example, because if count is an integer, then evaluating count >= 4 and count > 3 will produce the same results -- true for count >= 4, false otherwise. That wouldn't be the case if count is a floating-point value (but then, a floating-point value named "count" would raise other concerns.)

Dan Breslau
Doug didn’t give a precise description about what result he expected (“printing bye and lol” is not a precise description). That’s why I just wrote a working `switch` example and an equivalent `if`-`else` example to that.
Gumbo
You know, I missed that: We're all so hard-wired to include a break in each case clause; it didn't occur to me that the OP *wants* both cases to execute. I'm going to update my answer to cover that scenario.
Dan Breslau