Numeric comparison failure in a switch statement - javascript

"original post" : This function should compare the value of 'a' with several other values, but always defaults. My test shows that the value of 'a' or 'b' is never changed. Do I have the case a > statement incorrect or elsewhere?
Now I understand that I can not use comparison in the case statement:
Should I use a bunch of if statements and a while (a <> = 0) to do the multiple checking and decrementing?
The snippit below shows 'a' with a particular value. In the full function, actually 'a' gets a value from a random number in another function. It must be checked against 16 possible values and decremented, then rechecked until it finally reaches 0. The comparison values are actually powers of 2 (1 through 16).
function solution() {
var a = 18000;
var b = 0;
switch (a) {
case a > 30000:
a = a - 30000;
b = b++;
break;
case a > 16000:
b = b++; a = a - 16000;
break;
case a > 8000:
b = b++; a = a - 8000;
break;
default:
c = "defaulted!, Why?";
break;
}
window.alert (a + " " + b + " " + c);
}

Don't use switch for range checks like this. It's possible with
switch (true) {
case (a > 30000):
a = a - 30000;
b = b++;
but just don't do that.
Use if/else instead. While switch is really just an abstract if/else construct, use it for things like this:
switch(a){
case 1: ...
}

In a nutshell, you can't use boolean expressions in switch case labels. You'll need to rewrite the code as a series of if statements.

Related

Javascript switch statement calculation called by another function to display result calculation

I need to display a calculation made on switch statement.
The application should have two functions: one to calculate the ranking and one to display the ranking using switch statement to determine the raking as a parameter. it should have the "Senior Master" in the console.
The ranking system is as follows.
Ranking
Rating Points
Senior master
2400 +
National master
2200–2399
Expert
2000–2199
Class A
1800–1999
Class B
1600–1799
The display function should call the calculate function, passing the player ranking points as an argument to that function.
Example output of the application:
Senior Master
I tried using only the switch statement getting the result of the supposed calculation. I am still very confused as I am supposed to display the calculation in a second function.
I am having a result that does not seems correct.
here's the my code.
(function (seniorMaster) { // Self executing function. Protects global space.
function calculateRanking() {
seniorMaster = "2400 + ";
switch (seniorMaster) {
case ("2400 + "):
("Senior Master");
break;
case ("2200 - 2399"):
console.log("National Master");
break;
case ("2000 - 2199"):
console.log("Expert");
break;
case ("1800 - 1999"):
console.log("Class A");
break;
case ("1600 - 1799"):
console.log("Class B");
}
}
calculateRanking(); // need another function to display the raking
})();
function display(){ // not sure if the second function is correct
console.log("Senior Master")
}display()
I would not use a switch statement to print the result, but if you really need to, I would create two functions, like so:
function getRank(strRank) {
const rank = parseInt(strRank);
if (rank >= 2400) return "Senior Master";
if (rank >= 2200 && rank <= 2399) return "National Master";
if (rank >= 2000 && rank <= 2199) return "Expert";
if (rank >= 1800 && rank <= 1999) return "Class A";
if (rank >= 1600 && rank <= 1799) return "Class B";
else return "No rank";
}
function printRank(rank) {
switch (rank) {
case "Senior Master":
case "National Master":
case "Expert":
case "Class A":
case "Class B":
console.log(rank);
break;
default:
console.log("No matching rank");
break;
}
}
printRank(getRank("2400")); // => "Senior Master"
There are a few mistakes in your code.
You are not using console.log with senior-master case
case ("2400 + "):
("Senior Master"); // no console.log here.
break;
You cannot use calculateRanking(); inside display() because calculateRanking() is outside the scope of display()
You want to pass ranking inside calculateRanking() then first make it something like calculateRanking(seniorMaster) that will help you to pass rank/score parameter in calculateRanking(seniorMaster)
put display() inside the self executing function to allow it access calculateRanking function.
finally the code should be like
(function (/*seniorMaster*/) { // you can remove the seniorMaster
// parameter if it is not intended to use once.
function calculateRanking(seniorMaster) { //pass argument with it so
//that it could perform action according to input
switch (seniorMaster) {
// if you don't want to use string comparsion but interested
// to use numeric comparison then use
case ("2400 + "): // case (seniorMaster >= 2400):
console.log("Senior Master");
break;
case ("2200 - 2399"):
// case (seniorMaster >= 2200 && seniorMaster < 2400):
console.log("National Master");
break;
case ("2000 - 2199"): // case (seniorMaster >= 2000 && seniorMaster < 2200):
console.log("Expert");
break;
case ("1800 - 1999"): // case (seniorMaster >= 1800 && seniorMaster < 2000):
console.log("Class A");
break;
case ("1600 - 1799"): // case (seniorMaster >= 1600 && seniorMaster < 1800):
console.log("Class B");
}
}
//calculateRanking(seniorMaster); --- You should be more specific to use it here as
// I don't think it would be useful to call it here if you want to
// use display() to display ranking otherwise you are free to use it.
//You don't require display() but still if there is
//some specific purpose of it you may use it
function display(){
//call the function here
//here you
var seniorMaster = "2400 + "; // if you want to go with numeric comparison use ---
//var seniorMaster = Number_Value; (where Number_Value is any +Integer)
calculateRanking(seniorMaster);
}
display();
})();

why does this simple switch statement always run the default

Ok guys, It seems like this switch statement is forever doomed to NOT work.
The initial idea was to create a variable x which is a prompt, the user will have to select enter any number and that would be the value of x.
Then under the first case of the switch, if x is less than 0.5 then it will simply console.log "less".
If x is more than 0.5 it will simply console.log "more".
If for some reason the program didn't work as expected the default is to console.log "this is the default"
Then i added a console.log of x in the end just to know what number did the user enter.
Lets try it!
I tried and tried and regardless of what number i enter it always printed "this is the default". Then printed the value of x.
I ended up going Rambo and removing the prompt and declaring x to be 0.6. It ought to print "more" but it still doesn't.
var x = 0.6;
switch (x) {
case x < 0.5:
console.log("less");
break;
case x > 0.5:
console.log("more");
break;
default:
console.log("its the dflt");
};
console.log(x);
So I'm wondering whats wrong with this code. Help
switch compares what you switch with against the cases. So, if you have case x < 0.5: which you want to run, that case will run if the expression you switched against was true:
var x = 0.6;
switch (true) {
case x < 0.5:
console.log("less");
break;
case x > 0.5:
console.log("more");
break;
default:
console.log("its the dflt");
};
console.log(x);
If you switch against x itself, a case will only run if the case evaluates to the same value as x, which, here, is 0.6, eg:
var x = 0.6;
switch (x) {
case 0.6:
console.log('x is exactly 0.6');
break;
default:
console.log("x is something other than 0.6");
};
console.log(x);
But that's not flexible at all, and isn't what you want.
Personally, I'd prefer if/else, it's a lot easier to read (and, as some points out in comments, is a lot faster):
var x = 0.6;
if (x < 0.5) {
console.log("less");
} else if (x > 0.5) {
console.log("more");
} else {
console.log('neither less nor more; equal or NaN');
}
Switch compares the value of x to the value of the cases. In your code x < 0.5 evaluates to true. Instead of going to that case like if-statements, the switch case compares x and true. Since x is a number, x will never equal true so the default case is always taken.
I would use if-statements instead of a switch in this instance. Switches are better for enumerations (checking if x is a specific value out of a set of values, not a range of values)
CertainPerformance has answered you question very well however if you still don't understand how to use switch I would recommend you use "if statements" until you have the time to read more on using switch.
var x = 0.6;
if (x < 0.5) {
console.log("less");
}
else if (x > 0.5) {
console.log("more");
}
else {
console.log("its the dflt");
}
console.log(x);
Hope this is easier for you :)

How to correctly write a condition in switch? [duplicate]

This question already has answers here:
javascript switch(true)
(5 answers)
Closed 5 years ago.
Good afternoon!
Why does the first option work - switch (true), and the second option does not work - switch (a)?
First:
var a= prompt('Enter value', '');
switch(true)
{
case a>10:
alert('a>10');
break;
case a<10:
alert('a<10');
break;
default:
alert('a===10');
Second:
var a= prompt('Enter value', '');
switch(a)
{
case a>10:
alert('a>10');
break;
case a<10:
alert('a<10');
break;
default:
alert('a===10');
Why does the first option work - switch (true), and the second option
does not work - switch (a)?
As per documentation
The switch statement evaluates an expression, matching the
expression's value to a case clause, and executes statements
associated with that case.
So, in your first option true will match to either a < 10 or a > 10, however in second option, a being a string may not match to either of them.
Edit: I just realize OP ask for the difference instead of why it won't work, sorry for misunderstanding the question
It should work nicely
var a = prompt('Enter value', '');
switch (true) {
case (a > 10):
alert("a > 10");
break;
case (a < 10):
alert("a < 10");
break;
default:
alert('a == 10');
}
It's because a > 10 is true, like the switch(true), while switch(a) was passed a, which is not true. Of course, you should cast a. a = +a or use parseInt() or parseFloat().
Here's what you probably meant to do:
var a = prompt('Enter value');
if(+a > 10){
alert('a > 10');
}
else if(a !== '' && +a < 10){
alert('a < 10');
}
else if(+a === 10){
alert('a === 10');
}
else{
alert('Really, you should avoid using prompt and alert!');
}
// notice this is less code than that pointless switch
You need to convert the user input from a string to an integer, like so
a = parseInt(a)

Multiple variables with a switch (Javascript) [duplicate]

I am a newbie when it comes to JavaScript and it was my understanding that using one SWITCH/CASE statements is faster than a whole bunch of IF statements.
However, I want to use a SWITCH/CASE statement with two variables.
My web app has two sliders, each of which have five states. I want the behavior to be based on the states of these two variables. Obviously that is a whole heck of a lot of IF/THEN statements.
One way I thought about doing it was concatenating the two variables into one and then I could SWITCH/CASE that.
Is there a better way of accomplishing a SWITCH/CASE using two variables ?
Thanks !
Yes you can also do:
switch (true) {
case (var1 === true && var2 === true) :
//do something
break;
case (var1 === false && var2 === false) :
//do something
break;
default:
}
This will always execute the switch, pretty much just like if/else but looks cleaner. Just continue checking your variables in the case expressions.
How about a bitwise operator? Instead of strings, you're dealing with "enums", which looks more "elegant."
// Declare slider's state "enum"
var SliderOne = {
A: 1,
B: 2,
C: 4,
D: 8,
E: 16
};
var SliderTwo = {
A: 32,
B: 64,
C: 128,
D: 256,
E: 512
};
// Set state
var s1 = SliderOne.A,
s2 = SliderTwo.B;
// Switch state
switch (s1 | s2) {
case SliderOne.A | SliderTwo.A :
case SliderOne.A | SliderTwo.C :
// Logic when State #1 is A, and State #2 is either A or C
break;
case SliderOne.B | SliderTwo.C :
// Logic when State #1 is B, and State #2 is C
break;
case SliderOne.E | SliderTwo.E :
default:
// Logic when State #1 is E, and State #2 is E or
// none of above match
break;
}
I however agree with others, 25 cases in a switch-case logic is not too pretty, and if-else might, in some cases, "look" better. Anyway.
var var1 = "something";
var var2 = "something_else";
switch(var1 + "|" + var2) {
case "something|something_else":
...
break;
case "something|...":
break;
case "...|...":
break;
}
If you have 5 possibilities for each one you will get 25 cases.
First, JavaScript's switch is no faster than if/else (and sometimes much slower).
Second, the only way to use switch with multiple variables is to combine them into one primitive (string, number, etc) value:
var stateA = "foo";
var stateB = "bar";
switch (stateA + "-" + stateB) {
case "foo-bar": ...
...
}
But, personally, I would rather see a set of if/else statements.
Edit: When all the values are integers, it appears that switch can out-perform if/else in Chrome. See the comments.
I don't believe a switch/case is any faster than a series of if/elseif's. They do the same thing, but if/elseif's you can check multiple variables. You cannot use a switch/case on more than one value.
If the action of each combination is static, you could build a two-dimensional array:
var data = [
[1,2,3,4,5],
[6,7,8,9,10],
[11,12,13,14,15],
[16,17,18,19,20],
[21,22,23,24,25]
];
The numbers in above example can be anything, such as string, array, etc. Fetching the value is now a one-liner (assuming sliders have a value range of [0,5):
var info = data[firstSliderValue][secondSliderValue];
You could give each position on each slider a different binary value from 1 to 1000000000
and then work with the sum.
Yeah, But not in a normal way. You will have to use switch as closure.
ex:-
function test(input1, input2) {
switch (true) {
case input1 > input2:
console.log(input1 + " is larger than " + input2);
break;
case input1 < input2:
console.log(input2 + " is larger than " + input1);
default:
console.log(input1 + " is equal to " + input2);
}
}
I did it like this:
switch (valueA && valueB) {
case true && false:
console.log(‘valueA is true, valueB is false’)
break;
case ( true || false ) && true:
console.log(‘valueA is either true or false and valueB is true’)
break;
default:
void 0;
}

jquery Using ranges in switch cases?

Switch cases are usually like
Monday:
Tuesday:
Wednesday:
etc.
I would like to use ranges.
from 1-12:
from 13-19:
from 20-21:
from 22-30:
Is it possible? I'm using javascript/jquery by the way.
you could try abusing the switch fall through behaviour
var x = 5;
switch (x) {
case 1: case 2: case 3: case 4: ...
break;
case 13: case 14: case 15: ...
break;
...
}
which is very verbose
or you could try this
function checkRange(x, n, m) {
if (x >= n && x <= m) { return x; }
else { return !x; }
}
var x = 5;
switch (x) {
case checkRange(x, 1, 12):
//do something
break;
case checkRange(x, 13, 19):
...
}
this gets you the behaviour you would like. The reason i return !x in the else of checkRange is to prevent the problem of when you pass undefined into the switch statement. if your function returns undefined (as jdk's example does) and you pass undefined into the switch, then the first case will be executed. !x is guaranteed to not equal x under any test of equality, which is how the switch statement chooses which case to execute.
Late to the party, but upon searching for an answer to the same question, I came across this thread. Currently I actually use a switch, but a different way. For example:
switch(true) {
case (x >= 1 && x <= 12):
//do some stuff
break;
case (x >= 13 && x <= 19):
//do some other stuff
break;
default:
//do default stuff
break;
}
I find this a lot easier to read than a bunch of IF statements.
You can make interesting kludges. For example, to test a number against a range using a JavaScript switch, a custom function can be written. Basically have the function test a give n value and return it if it's in range. Otherwise returned undefined or some other dummy value.
<script>
// Custom Checking Function..
function inRangeInclusive(start, end, value) {
if (value <= end && value >= start)
return value; // return given value
return undefined;
}
// CODE TO TEST FUNCTION
var num = 3;
switch(num) {
case undefined:
//do something with this 'special' value returned by the inRangeInclusive(..) fn
break;
case inRangeInclusive(1, 10, num):
alert('in range');
break;
default:
alert('not in range');
break;
}
</script>
This works in Google Chrome. I didn't test other browsers.
Nope, you need to use an if/else if series to do this. JavaScript isn't this fancy. (Not many languages are.)

Categories