Typescript switch case with logical and
Asked Answered
K

4

19

I am trying to write a switch statement but it doesn't seem to work how I want.

getExerciseDescription(exerciseId, intensity_level){

    alert(exerciseId + " " + intensity_level)

    switch (exerciseId && intensity_level) {
        case (1 && 1):
        this.header="Exercise 1 Level 1";
        this.instructions="Exercise 1 Level 1";
        break;
        case (1 && 2):
        this.header="Exercise 1 Level 2";
        this.instructions="Exercise 1 Level 2";
        break;  


        case (2 && 1):
        this.header="Exercise 2 Level 1";
        this.instructions="Exercise 2 Level 1";
        break;  
        case (2 && 2):
        this.header="Exercise 2 Level 2";
        this.instructions="Exercise 2 Level 2";
        break;

        default:
        this.header="Default";
        this.instructions="Default";
        break;
    }

    return new Popup(this.header, this.instructions);
} 

The alerts gives 2 and 1 but the returned value is for (1 && 1). Why is it so? How can I fix this?

Kiri answered 5/3, 2017 at 18:21 Comment(0)
W
25

You just can't use a switch like that. (1 && 1) == (2 && 1) == 1 and (1 && 2) == (2 && 2) == 2, so you're doing the equivalent of:

    switch (exerciseId && intensity_level) {
        case (1): //...
        case (2): //...

        case (1): // same as above
        case (2): // same as above

        default:
        //...
   }

So of course the lower two cases will never execute. You're better of just using if and else if statements, or maybe nested switches if you want.

You could also do something like:

switch (exerciseId + " " + intensity_level) {
    case("1 1"): ...
    case("1 2"): ...
    case("2 1"): ...
    case("2 2"): ...
Westhead answered 5/3, 2017 at 18:31 Comment(1)
Just be warned, you take a performance hit comparing strings instead of numbers. Although with a string length of 3, it's probably not going to make any noticeable impact - see https://mcmap.net/q/444453/-is-javascript-string-comparison-just-as-fast-as-number-comparisonIntermingle
I
3

That isn't how a switch statement will evaluate. For your scenario it will always evaluate to the 2nd integer in the logical and &&.

(More information about Logical Operators)

Logical AND (&&)

expr1 && expr2

Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.

You actually don't even need to use a switch, you can write it with a simple if

if (exerciseId <= 2 && intensity_level <= 2){
    this.header=`Exercise ${exerciseId} Level ${intensity_level}`;
    this.instructions=`Exercise ${exerciseId} Level ${intensity_level}`;
} else {
    this.header="Default";
    this.instructions="Default";
}
Intermingle answered 5/3, 2017 at 18:31 Comment(5)
"Exercise 1 Level 1" for header and content was just an example, actually for each case there are different textual headers and instructions. So if else would be difficult.Kiri
Ok - you will most likely need to resort to multiple if statements thenIntermingle
I tried the above solution with string, it is lengthy but it worked. this.switchString=exerciseId + " " + intensity_level and then switch (this.switchString){case ("1 1"): ..}Kiri
String comparison is significantly slower than with numbers. I would advise against using strings just so you can use a switch statementIntermingle
Okay sure. I will modify the code accordingly then. Thanks!Kiri
C
3

You can use switch(true) then now you can use logical operator on case.

switch (true) 
{
        case (1 && 1):
        this.header="Exercise 1 Level 1";
        this.instructions="Exercise 1 Level 1";
        break;
        case (1 && 2):
        this.header="Exercise 1 Level 2";
        this.instructions="Exercise 1 Level 2";
        break;  

        case (2 && 1):
        this.header="Exercise 2 Level 1";
        this.instructions="Exercise 2 Level 1";
        break;  
        case (2 && 2):
        this.header="Exercise 2 Level 2";
        this.instructions="Exercise 2 Level 2";
        break;

        default:
        this.header="Default";
        this.instructions="Default";
        break;
    }
Chloe answered 9/3, 2022 at 2:9 Comment(1)
From version 5.3, TS does a better job at narrowing that swich(true) idiom: devblogs.microsoft.com/typescript/…Acadia
M
0

The logical operators &&, || and ! always return true or false so the possible switch cases are only true and false. You should go with strings or numbers cases only.

Mongol answered 5/3, 2017 at 18:30 Comment(1)
Actually, the expression 2 && 2 evaluates to 2 and not a booleanMyramyrah

© 2022 - 2024 — McMap. All rights reserved.