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

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

Related

How do i make switch and if statement in one function

function texas(val) {
var answer = "";
switch(val) {
case 1:
case 2:
case 3:
var answer = "low";
case 4:
case 5:
case 6:
var answer = "medium";
break;
} else if(val => 7) {
var answer = "Huge"
}
return answer;
}
it says error Declaration or statement expected. ts(1128) [13, 7]
and it poits at the else if statement
You can use the "default" keyword, but you should probably update your code in order to handle the cases in which the value of the parameter is not positive or not a number:
function texas(val) {
if (val <= 0 || isNan(val)) {
throw new InvalidOperationException("val should be a positive number");
}
switch(val) {
case 1:
case 2:
case 3:
return "low";
case 4:
case 5:
case 6:
return "medium";
default:
return "Huge"
}
}
It's >= and the elsehas to be deleted. The varfor answer is unnecesary, just declare it once with let. You forgot the break in case 3:.
function texas(val) {
let answer = "";
switch(val) {
case 1:
case 2:
case 3:
answer = "low";
break;
case 4:
case 5:
case 6:
answer = "medium";
break;
}
if(val >= 7) {
answer = "Huge"
}
return answer;
}
console.log(texas(2));
console.log(texas(8));
You just need to return in the switch
function texas(val) {
var answer = "";
switch(val) {
case 1:
case 2:
case 3:
var answer = "low";
return answer;
case 4:
case 5:
case 6:
var answer = "medium";
return answer;
}
if(val => 7) {
var answer = "Huge"
}
return answer;
}
The syntax does not allow to put an else after a switch. else only makes sense in combination with an if statemen. But switch has a default: case which most closely matches your intention (hopefully):
function texas(val) {
var answer = "";
switch(val) {
case 1:
case 2:
case 3:
var answer = "low";
break;
case 4:
case 5:
case 6:
answer = "medium";
break;
default:
if(val >= 7) {
answer = "Huge"
}
// decide what should happen if val is 0, -1 or not even a number (e.g. texas('gotcha!')
break;
}
return answer;
}
Don't forget to put break in your cases, otherwise execution will "fall through" and execute the next cases. You would never end up with "low"
You can't use an if statement within a switch block.
You do have the default option tho -
function texas(val) {
var answer = "";
switch(val) {
case 1:
case 2:
case 3:
answer = "low";
case 4:
case 5:
case 6:
answer = "medium";
break;
default:
answer = val >= 7 ? "Huge" : "Invalid";
break;
}
return answer;
Note that if you have a minus / negative answer, it'll also fall into this clause, but you can the the value of answer with an inline ?: if statement...
You can't put the else after the switch block as people have stated above. switch statement is better for multi way branching and fixed data values. On the other side, if statement is better for boolean values. You can do something like this. It might not be the shortest line of codes, but just so you that there's another approach:
function texas(val) {
let answer = "";
switch (true) {
case (val == 1 || val == 2 || val == 3):
answer = "low";
break;
case (val == 4 || val == 5 || val == 6):
answer = "medium";
break;
case (val >= 7):
answer = "huge";
break;
}
return answer;
}

Why can I not view an updated count for a variable with console.log in Javascript?

I currently have this code below, it is supposed to emulate a card counting system, in which different characters increment/decrement the count when passed. The code below runs successfully, but when I attempt console.log(cc(2,3,4,5,6); it returns 1 Bet, when I know the code runs 5 Bet, as those characters should increment the count, yet console.log does not return the accurate count, I assume this is due to scope? But I would like if someone could explain why count isn't accurately returned.
var count = 0;
function cc(card) {
switch(card) {
case 2:
case 3:
case 4:
case 5:
case 6:
count += 1;
break;
case 7:
case 8:
case 9:
count += 0;
break;
case 10:
case 'J':
case 'Q':
case 'K':
case 'A':
count -= 1;
break;
}
if (count > 0) {
return count + " Bet";
}
else {
return count + " Hold";
}
}
cc(2,3,4,5,6); \\ returns 5 Bet
console.log(cc(2,3,4,5,6)); \\ returns 2 Bet
var count = 0;
const bet = card => {
switch (card) {
case 2:
case 3:
case 4:
case 5:
case 6:
count += 1;
break;
case 7:
case 8:
case 9:
count += 0;
break;
case 10:
case "J":
case "Q":
case "K":
case "A":
count -= 1;
break;
}
};
function cc(...moves) {
moves.forEach(bet);
if (count > 0) {
return count + " Bet";
} else {
return count + " Hold";
}
}
console.log(cc(2, 3, 4, 5, 6)); // returns 5 Bet
console.log(cc(2, 3, 4, 5, 6)); // returns 10 Bet
Use arguments or splat operator to get all arguments passed and then loop it:
function cc(...cards) {
var count = 0;
var card;
for (var i = 0; i < cards.length; i++) {
card = cards[i];
switch (card) {
case 2:
case 3:
case 4:
case 5:
case 6:
count += 1;
break;
case 7:
case 8:
case 9:
count += 0;
break;
case 10:
case 'J':
case 'Q':
case 'K':
case 'A':
count -= 1;
break;
}
}
if (count > 0) {
return count + " Bet";
} else {
return count + " Hold";
}
}
cc(2, 3, 4, 5, 6); // returns 5 Bet
console.log(cc(2, 3, 4, 5, 6)); // returns 2 Bet
You have two major problems.
First, your count need to start at zero every time you call cc(). Because you have declared count outside the function, its values is preserved between calls to cc(). By declaring it inside the function, it's initialized to zero before it starts counting the card values.
(Unless you want to continue to the previous count, in which case you should keep it declared outside the function)
Second, your function only accepts one argument. You need to make it accept a list of arguments. This can be done simply with the spread operator .... Then you need to loop through each card value and do the count.
function cc(...cards) { // accept a list of card values as arguments.
let count = 0
for (const card of cards) { // loop through all card values.
switch (card) {
case 2:
case 3:
case 4:
case 5:
case 6:
count += 1
break
case 7:
case 8:
case 9:
count += 0
break
case 10:
case 'J':
case 'Q':
case 'K':
case 'A':
count -= 1
break
}
}
if (count > 0) {
return `${count} Bet`
}
return `${count} Hold`
}
cc(2, 3, 4, 5, 6) // returns 5 Bet
console.log(cc(2, 3, 4, 5, 6)) // returns 5 Bet
console.log(cc(2, 3, 4, 5, 6)) // returns 5 Bet

switch case of greater than or less than variable [duplicate]

This question already has answers here:
Expression inside switch case statement
(8 answers)
Closed 3 years ago.
I use this code to enter a number and compare it using less and greater than within switch case how should I do to get the correct result, only default can works
var sum=prompt("enter sum:");
// sum=50;
switch(sum)
{
case sum=0:
alert("sucess");
break;
case sum>50:
alert("also sucess");
break;
case sum<50:
alert("failed");
default:
alert("there is errorrrr");
}
You can use switch (true):
switch (true) {
case sum === 0:
alert('success');
break;
case sum < 50:
alert('also success');
break;
case sum > 50:
alert('failed');
break;
default:
alert('there is an error.')
break;
}
Note that in your code, the first case is actually an assignment and modify sum to set it to 0.
It actually doesn't work, as you expect, the switch statement is compared against all cases, such as :
switch (something)
{
case 1: // something == 1 ?
// ....
}
Actually, what you have write was interpreted such as
var sum = 42;
switch(sum)
{
case sum < 50: // sum == sum < 50 ? -> 42 == 42 < 50 ? -> 42 == true ? false !
// ...
Instead, you can use a switch true statement.
// v------- convert the prompt to a numeric value
let sum = + prompt("enter sum:");
switch(true)
{
// VV----- notice the double equal
case sum == 0: // true == sum == 0 ?
alert("sucess");
break;
case sum > 50:
alert("also sucess");
break;
case sum < 50:
alert("failed");
break; // <---- You forgot a break; there
default:
alert("there is errorrrr");
break;
}
ur idea works fine
sum=20;
switch(true)
{
case 50:
alert("sucess");
break;
case (sum>50):
alert("also sucess");
break;
case sum<50:
alert("failed");
break;
default:
alert("there is errorrrr");
}

Typescript switch case with logical and

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.

Javascript case statement in the switch Statement

I have a problem with the 'case' statement in the 'switch' statement in java script.
My question is how to write more than one number in the 'case' statement and save all the work on writing multiple of commands for each number , ill try to explain myself better. i want to write in the case statement the
number 10-14 (10,11,12,13,14).
how can i write it?
thanks for helping and sorry for my bad english.
name = prompt("What's your name?")
switch (name)
{
case "Ori":
document.write("<h1>" + "Hello there Ori" + "<br>")
break;
case "Daniel":
document.write("<h1>" + "Hi, Daniel." + "<br>")
break;
case "Noa":
document.write("<h1>" + "Noa!" + "<br>")
break;
case "Tal":
document.write("<h1>" + "Hey, Tal!" + "<br>")
break;
default:
document.write("<h1>" + name + "<br>")
}
age = prompt ("What's your age?")
switch (age)
{
case "10":
document.write("you are too little" + name)
break;
case "14":
document.write("So , you are in junior high school" + name)
break;
case "18":
document.write("You are a grown man" + name)
break;
default:
document.write("That's cool" + name)
break;
}
Check out this answer Switch on ranges of integers in JavaScript
In summary you can do this
var x = this.dealer;
switch (true) {
case (x < 5):
alert("less than five");
break;
case (x > 4 && x < 9):
alert("between 5 and 8");
break;
case (x > 8 && x < 12):
alert("between 9 and 11");
break;
default:
alert("none");
break;
}
but that sort of defeats the purpose of a switch statement, because you could just chain if-else statments. Or you can do this:
switch(this.dealer) {
case 1:
case 2:
case 3:
case 4:
// Do something.
break;
case 5:
case 6:
case 7:
case 8:
// Do something.
break;
default:
break;
}
use this, if you dont provide break then control will fall down, In this way you can match for group of numbers in switch.
case 10:
case 11:
case 12:
case 14:
case 15: document.write("i am less than or equal to 15");break;
Say you wanted to switch on a number 10-14 (10,11,12,13,14) you can chain the cases together:
switch(number) {
case 10:
case 11:
case 12:
case 13:
case 14:
alert("I'm between 10 and 14");
break;
default:
alert("I'm not between 10 and 14");
break;
}
You can simply omit the break; statement.
switch (2) {
case 1: case 2: case 3:
console.log('1 or 2 or 3');
break;
default:
console.log('others');
break;
}
I wanted to play with the concept a bit, I do not recommend this approach, however you could also rely on a function that will create a control flow function for you. This simply allows some syntaxic sugar.
var createCaseFlow = (function () {
var rangeRx = /^(\d)-(\d)$/;
function buildCases(item) {
var match = item.match(rangeRx),
n1, n2, cases;
if (match) {
n1 = parseInt(match[1], 10);
n2 = parseInt(match[2], 10);
cases = [];
for (; n1 <= n2; n1++) {
cases.push("case '" + n1 + "':");
}
return cases.join('');
}
return "case '" + item + "':";
}
return function (cases, defaultFn) {
var fnStrings = ['switch (value.toString()) { '],
k;
for (k in cases) {
if (cases.hasOwnProperty(k)) {
fnStrings.push(k.split(',').map(buildCases).join('') + "return this[0]['" + k + "'](); break;");
}
}
defaultFn && fnStrings.push('default: return this[1](); break;');
return new Function('value', fnStrings.join('') + '}').bind(arguments);
};
})();
var executeFlow = createCaseFlow({
'2-9': function () {
return '2 to 9';
},
'10,21,24': function () {
return '10,21,24';
}
},
function () {
return 'default case';
}
);
console.log(executeFlow(5)); //2 to 9
console.log(executeFlow(10)); //10,21,24
console.log(executeFlow(13)); //default case
You have already gotten a few answers on how to make this work. However, I want to point out a few more things. First off, personally, I wouldn't use a switch/case statement for this as there are so many similar cases – a classic if/elseif/else chain feels more appropriate here.
Depending on the use-case you could also extract a function and then use your switch/case (with more meaningful names and values, of course):
function getCategory (number) {
if(number > 20) {
return 3;
}
if(number > 15) {
return 2;
}
if(number > 8) {
return 1;
}
return 0;
}
switch( getCategory( someNumber ) ) {
case 0:
// someNumber is less than or equal to 8
break;
case 1:
// someNumber is any of 9, 10, 11, 12, 13, 14, 15
break;
// ...
}
If the intervals are equally spaced, you could also do something like this:
switch( Math.floor( someNumber / 5 ) ) {
case 0:
// someNumber is any one of 0, 1, 2, 3, 4
break;
case 1:
// someNumber is any one of 5, 6, 7, 8, 9
break;
// ...
}
Also, it should be noted that some people consider switch/case statements with fall-throughs (= leaving out the break; statement for come cases) bad practice, though others feel it's perfectly fine.

Categories