Typescript switch case with logical and - javascript

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?

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"): ...

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";
}

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;
}

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.

Related

Why does the logical OR operator in switch cases behave strangely?

The testMyNumber function seems to think numbers in the second position do not match.
Why do 4 and 10 return the default case?
function testMyNumber(number) {
switch (number) {
case 6:
return number+" is 6";
break;
case (3 || 4) :
return number+" is 3 or 4";
break;
case 9 || 10 :
return number+" is 9 or 10";
break;
default:
return number+" is not in 3,4,6,9,10";
break;
}
};
console.log(testMyNumber(6));
console.log(testMyNumber(3));
console.log(testMyNumber(4));
console.log(testMyNumber(9));
console.log(testMyNumber(10));
Is there a way to make this work?
Because it wasn't intended to be used this way.
|| returns its first operand if it's truthy, else its second operand.
3 || 4 returns 3 because 3 is truthy, therefore case will check only 3:
console.log(3 || 4); //3, because it is truthy
console.log(0 || 1); //1, because 0 is falsy
To make your code work, use separate cases that fall through:
function testMyNumber(number) {
switch (number) {
case 6:
return number+" is 6";
case 3:
case 4:
return number+" is 3 or 4";
case 9:
case 10:
return number+" is 9 or 10";
default:
return number+" is not in 3,4,6,9,10";
}
};
console.log(testMyNumber(6));
console.log(testMyNumber(3));
console.log(testMyNumber(4));
console.log(testMyNumber(9));
console.log(testMyNumber(10));
Why 4 returns default case?
Because (3 || 4) is equal to 3, so case (3 || 4): is the same as writing case 3:.
You are using incorrect syntax. Write it like this:
case 3:
case 4:
return number + " is 3 or 4";
Because (3 || 4) is 3 and its not 4, so it jumps to default.
console.log((3 || 4));
var test = 4;
switch(test){
case 3:
case 4:
console.log("3 and 4");
break;
default:
console.log("default");
}
Write that cases underneath
The reason is in two parts.
First of all, switch statements in JS cannot handle multiple values in a single case.
So what happens when you try to do so? Well see below.
console.log(3 || 4);
Now why does 3 || 4 evaluate to 3. To understand this, think about the OR operator with booleans.
bool_a || bool_b. If the bool_a is true, then the expression evaluates to true, think of this as evaluating to bool_a. If the value is false it will essentially return bool_b.
In Javascript this is exactly how things work. Just replace true and false with truthy and falsy.
console.log(0 || 2);
console.log([]|| 2);
console.log(''|| 2);
console.log(false|| 2);
console.log("aaa" || 2);
console.log(true || 2);
To do this the way you want
case 3:
case 4:
return number + " is 3 or 4"
If you do 3 || 4 the answer is 3.
The correct way to do this is like this
function testMyNumber(number) {
switch (number) {
case 6:
return number+" is 6";
break;
case 3:
case 4:
return number+" is 3 or 4";
break;
case 9:
case 10 :
return number+" is 9 or 10";
break;
default:
return number+" is not in 3,4,6,9,10";
break;
}
};
case (3 || 4) always evaluates to 3 because 3 is truthy.
You could instead use multiple cases:
function testMyNumber(number) {
switch (number) {
case 6:
return number+" is 6";
break;
case 3:
case 4:
return number+" is 3 or 4";
break;
case 9:
case 10:
return number+" is 9 or 10";
break;
default:
return number+" is not in 3,4,6,9,10";
break;
}
};
console.log(testMyNumber(6));
console.log(testMyNumber(3));
console.log(testMyNumber(4));
console.log(testMyNumber(9));
console.log(testMyNumber(10));
See the MDN switch docs.
Because of the way the syntax works in JavaScript, your case 4: is never defined.
When you say case (3 || 4):, you're telling JavaScript the name for just one case, the case of whatever your expression evaluates to. In this example, (3 || 4) evaluates to 3, so you're telling JavaScript case 3:.
The first code sample on MDN shows what you are trying to do

Why "if" works but "switch" doesn't work?

// It is simple code
var num = prompt("put number");
// This way is not worked
switch (num) {
case num > 0:
console.log("num++");
break;
case num < 0:
console.log(num-2);
break;
}
// But this worked
if (num > 0){
console.log(num++);
} else if (num < 0){
console.log(num -2);
}
My first way by "switch" is not worked but "if" method worked.
I tried all of thing for changing code or other ways but the same result.
Please guys help me.
Because the statement num > 0 inside you case will return true or false.
If you do this:
switch (true) {
case num > 0:
console.log("num++");
break;
case num < 0:
console.log(num-2);
break;
}
It will work.
Cases cannot be expressions, you must normalize your input first.
Although it is valid to place an expression in a case, in this scenario a more tried-and-true way of dealing with this is to first normalize your input first.
You can determine direction for example:
var num = parseInt(prompt("put number"), 10);
var direction = num < 0 ? -1 : 1;
switch (direction) {
case 1:
console.log("num++");
break;
case -1:
console.log(num - 2);
break;
}
The switch acts as a case switcher, meaning you cannot make comparisons to create cases, just list cases by case, and perform some function from this case. The if / else structure is suitable for making comparisons, as the expected result in the if call is always a boolean.
Example:
const a = 1;
if (a === 1) {
console.log('hello');
} else {
console.log('sad');
switch (a) {
case 1 : console.log('hello'); break;
default: console.log('sad'); break;
In your case, I recommend using if/else if/else, as it is more recommended.

FizzBuzz using JavaScript Switch [duplicate]

This question already has answers here:
javascript fizzbuzz switch statement
(8 answers)
Closed 4 years ago.
Can't seem to point out something obvious. This solution doesn't work. Please help?
FizzBuzz question: Print numbers from 1 to 100. Print Fizz instead of numbers divisible by 3. Print Buzz instead of numbers divisible by 5. Print FizzBuzz instead of numbers divisible by both 3 and 5.
for(var i = 1; i <= 100; i++) {
switch (i) {
case (i%3 === 0 && i%5 === 0):
console.log('FizzBuzz');
break;
case (i%3 === 0):
console.log('Fizz');
break;
case (i%5 === 0):
console.log('Buzz');
break;
default:
console.log(i);
}
}
The problem is, you are switching on the value of variable i. Then you are comparing that with expressions like i % 3 === 0, so the comparison becomes i === (i % 3 === 0).
Instead, you can switch on true, so any expression evaluating to true will be switched into.
for (var i = 1; i <= 100; i++) {
switch (true) {
case (i % 3 === 0 && i % 5 === 0):
console.log('FizzBuzz');
break;
case (i % 3 === 0):
console.log('Fizz');
break;
case (i % 5 === 0):
console.log('Buzz');
break;
default:
console.log(i);
}
}
A switch enters the branch if the case matches the value you are switching for, therefore:
switch (i) {
case (i%3 === 0 && i%5 === 0):
Will enter the first case if:
i === (i%3 === 0 && i%5 === 0)
E.g. for 15 it will be:
15 === true // -> false
so it wont enter the branch. Therefore instead of switching for i you have to switch for true:
switch(true) {
Did you try not to break the switch, because when it matches it won't print the other stuff it is supposed to? Maybe?

Nested switch statement in javascript

Is it possible to use nested switch statement in javascript.
My code is some what look like
switch(id1)
{
case 1:
switch(id2){
case 1:{
switch(id3){
case 1:{}
case 2:{}
}
}
case 2:{
switch(id4){
case 1:{}
case 2:{}
}
}
}
case 2:
}
If yes then it is a good practice to do or we can use any alternate approach.
Your approach is absolutely fine.
You can make the switch nesting less complex by using switch (true):
switch (true) {
case ((id1 === 1) && (id2 === 1) && (id3 === 1)) :
case ((id1 === 1) && (id2 === 1) && (id3 === 2)) :
case ((id1 === 1) && (id2 === 2) && (id3 === 1)) :
case ((id1 === 1) && (id2 === 2) && (id3 === 2)) :
case ((id1 === 2) && (id2 === 1) && (id3 === 1)) :
case ((id1 === 2) && (id2 === 1) && (id3 === 2)) :
case ((id1 === 2) && (id2 === 2) && (id3 === 1)) :
case ((id1 === 2) && (id2 === 2) && (id3 === 2)) :
}
Yes, you can use inner switch like this way,
Please check this demo : https://jsfiddle.net/1qsfropn/3/
var text;
var date = new Date()
switch (date.getDay()) {
case 1:
case 2:
case 3:
default:
text = "Looking forward to the Weekend";
break;
case 4:
case 5:
text = "Soon it is Weekend";
break;
case 0:
case 6:
switch(date.getFullYear()){
case 2015:
text = "It is Weekend of last Year.";
break;
case 2016:
text = "It is Weekend of this Year.";
break;
case 2017:
text = "It is Weekend of next Year.";
break;
default:
text = date.getDay();
break;
}
break;
}
document.getElementById("demo").innerHTML = text;`
You can use a nested switch statement but that can quickly become a spaghetti code and therefore it is not recommended. I would rather use functions with the nested switch statement for code clearance or maybe use recursive function depending on what the code is supposed to do.
This is only a pseudo-code but I hope it gives you some idea on how to implement it. You have to be carefull to make the recursion stop on some given value of the ID.
This pseudo-code increments the value of the ID by 1 if the value of the ID is 1, and increments by 2 if the value is 2. If the value is not 1 or 2 the recursion ends.
function recursiveSwitch(var id) {
switch(id) {
case 1:
recursiveSwitch(id + 1);
break;
case 2
recursiveSwitch(id + 2)
break;
default:
return;
}
}
Basically, it's possible but I think it depends on the complexity of the nesting if it's recommended to use nested switch statement or to use functions with the nested switch statement as Ómar Óskarsson has suggested.

Does switch statement start comparing cases from the top in this example?

I found this example to make range work with switch statement:
function GetText(value)
{
var result;
switch (true)
{
case ((value >= 26) && (value <= 50)):
result = ">= 26.";
break;
case ((value >= 1) && (value <= 25)):
result = "Between 1 and 25.";
break;
case (value == 0):
result = "Equals Zero.";
break;
}
return result;
}
But if I modify the code and remove the second check for the value the example will still work:
function GetText(value)
{
var result;
switch (true)
{
case ((value >= 26)):
result = ">= 26 .";
break;
case ((value >= 1)):
result = "Between 1 and 25.";
break;
case (value == 0):
result = "Equals Zero.";
break;
}
return result;
}
So if I passed 29 even that I have two true cases the first one will be selected. My question is that how switch statement works in most of programming languages it will start comparing from the top or its only in this case (and is it good or bad to write it like that?).
switch statement checks for matches from top to bottom.
From MDN docs on switch statement:
If a match is found, the program executes the associated statements. If multiple cases match the provided value, the first case that matches is selected, even if the cases are not equal to each other.
I would do something like this (with if and else if chains):
function GetText(value) {
var result;
if (value == 0) {
result = "Equals Zero.";
} else if (value <= 25) {
result = "Between 1 and 25.";
} else if (value <= 50) {
result = "Between 26 and 50.";
}
return result;
}

Categories