JavaScript: using a condition in switch case - javascript

How can I use a condition inside a switch statement for JavaScript?
In the example below, a case should match when the variable liCount is <= 5 and > 0; however, my code does not work:
switch (liCount) {
case 0:
setLayoutState("start");
var api = $("#UploadList").data("jsp");
api.reinitialise();
break;
case liCount <= 5 && liCount > 0:
setLayoutState("upload1Row");
var api = $("#UploadList").data("jsp");
api.reinitialise();
break;
case liCount <= 10 && liCount > 5:
setLayoutState("upload2Rows");
var api = $("#UploadList").data("jsp");
api.reinitialise();
break;
case liCount > 10:
var api = $("#UploadList").data("jsp");
api.reinitialise();
break;
default:
break;
}
Appreciate any advice!

This works:
switch (true) {
case liCount == 0:
setLayoutState('start');
var api = $('#UploadList').data('jsp');
api.reinitialise();
break;
case liCount<=5 && liCount>0:
setLayoutState('upload1Row');
var api = $('#UploadList').data('jsp');
api.reinitialise();
break;
case liCount<=10 && liCount>5:
setLayoutState('upload2Rows');
var api = $('#UploadList').data('jsp');
api.reinitialise();
break;
case liCount>10:
var api = $('#UploadList').data('jsp');
api.reinitialise();
break;
}
The only thing necessary is switch(true){...} and for your case expressions to evaluate to booleans.
It works because, the value we give to the switch is used as the basis to compare against. Consequently, the case expressions, also evaluating to booleans will determine which case is run. Could also turn this around, and pass switch(false){..} and have the desired expressions evaluate to false instead of true.. but personally prefer dealing with conditions that evaluate to truthyness. However, it does work too, so worth keeping in mind to understand what it is doing.
Eg: if liCount is 3, the first comparison is true === (liCount == 0), meaning the first case is false. The switch then moves on to the next case true === (liCount<=5 && liCount>0). This expression evaluates to true, meaning this case is run, and terminates at the break. I've added parentheses here to make it clearer, but they are optional, depending on the complexity of your expression.
It's pretty simple, and a neat way (if it fits with what you are trying to do) of handling a long series of conditions, where perhaps a long series of ìf() ... else if() ... else if () ... might introduce a lot of visual noise or fragility.
Use with caution, because it is a non-standard pattern, despite being valid code.

You've way overcomplicated that. Write it with if statements instead like this:
if(liCount == 0)
setLayoutState('start');
else if(liCount<=5)
setLayoutState('upload1Row');
else if(liCount<=10)
setLayoutState('upload2Rows');
$('#UploadList').data('jsp').reinitialise();
Or, if ChaosPandion is trying to optimize as much as possible:
setLayoutState(liCount == 0 ? 'start' :
liCount <= 5 ? 'upload1Row' :
liCount <= 10 ? 'upload2Rows' :
null);
$('#UploadList').data('jsp').reinitialise();

You want to use if statements:
if (liCount === 0) {
setLayoutState('start');
} else if (liCount <= 5) {
setLayoutState('upload1Row');
} else if (liCount <= 10) {
setLayoutState('upload2Rows');
}
$('#UploadList').data('jsp').reinitialise();

See dmp's answer below. I'd delete this answer if I could, but it was accepted so this is the next best thing :)
You can't. JS Interpreters require you to compare against the switch statement (e.g. there is no "case when" statement). If you really want to do this, you can just make if(){ .. } else if(){ .. } blocks.

You can use fall-through method in switch case.
const x = 'Welcome';
switch (x) {
case 'Come':
console.log(1)
break;
case 'Welcome':
case 'Wel':
case 'come':
console.log(2)
break;
case 'Wel':
console.log(3)
break;
default:
break;
}
> Result => 2

switch (true) {
case condition0:
...
break;
case condition1:
...
break;
}
will work in JavaScript as long as your conditions return proper boolean values, but it doesn't have many advantages over else if statements.

if the possible values are integers you can bunch up cases.
Otherwise, use ifs.
var api, tem;
switch(liCount){
case 0:
tem= 'start';
break;
case 1: case 2: case 3: case 4: case 5:
tem= 'upload1Row';
break;
case 6: case 7: case 8: case 9: case 10:
tem= 'upload2Rows';
break;
default:
break;
}
if(tem) setLayoutState((tem);
api= $('#UploadList').data('jsp');
api.reinitialise();

That's a case where you should use if clauses.

If that's what you want to do, it would be better to use if statements. For example:
if(liCount == 0){
setLayoutState('start');
}
if(liCount<=5 && liCount>0){
setLayoutState('upload1Row');
}
if(liCount<=10 && liCount>5){
setLayoutState('upload2Rows');
}
var api = $('#UploadList').data('jsp');
api.reinitialise();

Your code does not work because it is not doing what you are expecting it to do. Switch blocks take in a value, and compare each case to the given value, looking for equality. Your comparison value is an integer, but most of your case expressions resolve to a boolean value.
So, for example, say liCount = 2. Your first case will not match, because 2 != 0. Your second case, (liCount<=5 && liCount>0) evaluates to true, but 2 != true, so this case will not match either.
For this reason, as many others have said, you should use a series of if...then...else if blocks to do this.

Notice that we don't pass score to the switch but true. The value we give to the switch is used as the basis to compare against.
The below example shows how we can add conditions in the case: without any if statements.
function getGrade(score) {
let grade;
// Write your code here
switch(true) {
case score >= 0 && score <= 5:
grade = 'F';
break;
case score > 5 && score <= 10:
grade = 'E';
break;
case score > 10 && score <= 15:
grade = 'D';
break;
case score > 15 && score <= 20:
grade = 'C';
break;
case score > 20 && score <= 25:
grade = 'B';
break;
case score > 25 && score <= 30:
grade = 'A';
break;
}
return grade;
}

If you want pass any value in switch statement
and then apply condition on that passing value and
evaluate statement then you have to write switch
statement under an function and pass parameter in that
function and then pass true in switch expression like the
below example.
function numberChecker(num){
let age;
switch(true){
case num >= 0 && num <= 10:
age = "Child";
break;
case num >= 10 && num <= 20:
age = "Teenager";
break;
case num >= 20 && num <= 30:
age = "Young";
break;
default:
age = "Undefined!! Enter Age Between 0 - 30";
break;
}
console.log("WOW You Are " + age);
}
numberChecker(15);

Although in the particular example of the OP's question, switch is not appropriate, there is an example where switch is still appropriate/beneficial, but other evaluation expressions are also required. This can be achieved by using the default clause for the expressions:
switch (foo) {
case 'bar':
// do something
break;
case 'foo':
// do something
break;
... // other plain comparison cases
default:
if (foo.length > 16) {
// something specific
} else if (foo.length < 2) {
// maybe error
} else {
// default action for everything else
}
}

Related

Javascript Bitwise Operator not behaving correctly [duplicate]

How can I use a condition inside a switch statement for JavaScript?
In the example below, a case should match when the variable liCount is <= 5 and > 0; however, my code does not work:
switch (liCount) {
case 0:
setLayoutState("start");
var api = $("#UploadList").data("jsp");
api.reinitialise();
break;
case liCount <= 5 && liCount > 0:
setLayoutState("upload1Row");
var api = $("#UploadList").data("jsp");
api.reinitialise();
break;
case liCount <= 10 && liCount > 5:
setLayoutState("upload2Rows");
var api = $("#UploadList").data("jsp");
api.reinitialise();
break;
case liCount > 10:
var api = $("#UploadList").data("jsp");
api.reinitialise();
break;
default:
break;
}
Appreciate any advice!
This works:
switch (true) {
case liCount == 0:
setLayoutState('start');
var api = $('#UploadList').data('jsp');
api.reinitialise();
break;
case liCount<=5 && liCount>0:
setLayoutState('upload1Row');
var api = $('#UploadList').data('jsp');
api.reinitialise();
break;
case liCount<=10 && liCount>5:
setLayoutState('upload2Rows');
var api = $('#UploadList').data('jsp');
api.reinitialise();
break;
case liCount>10:
var api = $('#UploadList').data('jsp');
api.reinitialise();
break;
}
The only thing necessary is switch(true){...} and for your case expressions to evaluate to booleans.
It works because, the value we give to the switch is used as the basis to compare against. Consequently, the case expressions, also evaluating to booleans will determine which case is run. Could also turn this around, and pass switch(false){..} and have the desired expressions evaluate to false instead of true.. but personally prefer dealing with conditions that evaluate to truthyness. However, it does work too, so worth keeping in mind to understand what it is doing.
Eg: if liCount is 3, the first comparison is true === (liCount == 0), meaning the first case is false. The switch then moves on to the next case true === (liCount<=5 && liCount>0). This expression evaluates to true, meaning this case is run, and terminates at the break. I've added parentheses here to make it clearer, but they are optional, depending on the complexity of your expression.
It's pretty simple, and a neat way (if it fits with what you are trying to do) of handling a long series of conditions, where perhaps a long series of ìf() ... else if() ... else if () ... might introduce a lot of visual noise or fragility.
Use with caution, because it is a non-standard pattern, despite being valid code.
You've way overcomplicated that. Write it with if statements instead like this:
if(liCount == 0)
setLayoutState('start');
else if(liCount<=5)
setLayoutState('upload1Row');
else if(liCount<=10)
setLayoutState('upload2Rows');
$('#UploadList').data('jsp').reinitialise();
Or, if ChaosPandion is trying to optimize as much as possible:
setLayoutState(liCount == 0 ? 'start' :
liCount <= 5 ? 'upload1Row' :
liCount <= 10 ? 'upload2Rows' :
null);
$('#UploadList').data('jsp').reinitialise();
You want to use if statements:
if (liCount === 0) {
setLayoutState('start');
} else if (liCount <= 5) {
setLayoutState('upload1Row');
} else if (liCount <= 10) {
setLayoutState('upload2Rows');
}
$('#UploadList').data('jsp').reinitialise();
See dmp's answer below. I'd delete this answer if I could, but it was accepted so this is the next best thing :)
You can't. JS Interpreters require you to compare against the switch statement (e.g. there is no "case when" statement). If you really want to do this, you can just make if(){ .. } else if(){ .. } blocks.
You can use fall-through method in switch case.
const x = 'Welcome';
switch (x) {
case 'Come':
console.log(1)
break;
case 'Welcome':
case 'Wel':
case 'come':
console.log(2)
break;
case 'Wel':
console.log(3)
break;
default:
break;
}
> Result => 2
switch (true) {
case condition0:
...
break;
case condition1:
...
break;
}
will work in JavaScript as long as your conditions return proper boolean values, but it doesn't have many advantages over else if statements.
if the possible values are integers you can bunch up cases.
Otherwise, use ifs.
var api, tem;
switch(liCount){
case 0:
tem= 'start';
break;
case 1: case 2: case 3: case 4: case 5:
tem= 'upload1Row';
break;
case 6: case 7: case 8: case 9: case 10:
tem= 'upload2Rows';
break;
default:
break;
}
if(tem) setLayoutState((tem);
api= $('#UploadList').data('jsp');
api.reinitialise();
That's a case where you should use if clauses.
If that's what you want to do, it would be better to use if statements. For example:
if(liCount == 0){
setLayoutState('start');
}
if(liCount<=5 && liCount>0){
setLayoutState('upload1Row');
}
if(liCount<=10 && liCount>5){
setLayoutState('upload2Rows');
}
var api = $('#UploadList').data('jsp');
api.reinitialise();
Your code does not work because it is not doing what you are expecting it to do. Switch blocks take in a value, and compare each case to the given value, looking for equality. Your comparison value is an integer, but most of your case expressions resolve to a boolean value.
So, for example, say liCount = 2. Your first case will not match, because 2 != 0. Your second case, (liCount<=5 && liCount>0) evaluates to true, but 2 != true, so this case will not match either.
For this reason, as many others have said, you should use a series of if...then...else if blocks to do this.
Notice that we don't pass score to the switch but true. The value we give to the switch is used as the basis to compare against.
The below example shows how we can add conditions in the case: without any if statements.
function getGrade(score) {
let grade;
// Write your code here
switch(true) {
case score >= 0 && score <= 5:
grade = 'F';
break;
case score > 5 && score <= 10:
grade = 'E';
break;
case score > 10 && score <= 15:
grade = 'D';
break;
case score > 15 && score <= 20:
grade = 'C';
break;
case score > 20 && score <= 25:
grade = 'B';
break;
case score > 25 && score <= 30:
grade = 'A';
break;
}
return grade;
}
If you want pass any value in switch statement
and then apply condition on that passing value and
evaluate statement then you have to write switch
statement under an function and pass parameter in that
function and then pass true in switch expression like the
below example.
function numberChecker(num){
let age;
switch(true){
case num >= 0 && num <= 10:
age = "Child";
break;
case num >= 10 && num <= 20:
age = "Teenager";
break;
case num >= 20 && num <= 30:
age = "Young";
break;
default:
age = "Undefined!! Enter Age Between 0 - 30";
break;
}
console.log("WOW You Are " + age);
}
numberChecker(15);
Although in the particular example of the OP's question, switch is not appropriate, there is an example where switch is still appropriate/beneficial, but other evaluation expressions are also required. This can be achieved by using the default clause for the expressions:
switch (foo) {
case 'bar':
// do something
break;
case 'foo':
// do something
break;
... // other plain comparison cases
default:
if (foo.length > 16) {
// something specific
} else if (foo.length < 2) {
// maybe error
} else {
// default action for everything else
}
}

usage of !(not) operator in switch case

// checking whether a number is a multiple of 3 or not
for (let number = 1; number <= 100; number++) {
switch (number % 3) {
case !0: // Here I have used !(not) but it's not helping, I only want to know why '!' is not helping
console.log(`${number} is not multiple of 3`);
break;
default:
console.log(`${number} is multiple of 3`)
}
}
Here the 1st case is not working. Code execution has no problems but the 1st case is not helping at all. The complete flow is going to the 'default:' code block only. Whenever the remainder is not equal to 0, the 1st case's code block should be executed, but it's always going to the default code block.
You can't do it in this way because !0 is always true in JavaScript so the loop always enters in the first case
Try it in this way
for (let number = 1; number <= 100 ;number++ ) {
if(number % 3){
console.log(`${number} is not multiple of 3`);
}
else{
console.log(`${number} is multiple of 3`);
}
}
The switch statement receives values on case statements, not expressions like the if. So, when js run your code, it will evaluate !0 to true (inverse of a falsy value is true).
You must replace your switch by if and elses:
for (let number = 1; number <= 100 ;number++ ) {
if ((number % 3) !== 0) {
console.log(`${number} is not multiple of 3`);
} else {
console.log(`${number} is multiple of 3`)
}
}
But you can still use a switch case statement if you invert the logic:
for (let number = 1; number <= 100 ;number++ ) {
switch (number % 3) {
case 0:
console.log(`${number} is multiple of 3`)
break;
default:
console.log(`${number} is not multiple of 3`);
}
}
But really makes no sense using a switch case in this situation since an if-else is much simpler and easier to read.
!0 evals to true, which is not equals to 1 or 2.
Consider writing it in this way:
for (let number = 1; number <= 100; number++) {
switch (number % 3) {
case 0:
console.log(`${number} is multiple of 3`)
break;
default:
console.log(`${number} is not multiple of 3`);
}
}
In JS, 0 is considered falsy that's why !0 will equals true ( not falsy ).
As for your switch, you could reverse your it and use a true as the switch values. The cases would then have the expression to check
for (let number = 1; number <= 100 ;number++ ) {
switch (true) {
case number % 3:
console.log(`${number} is not multiple of 3`);
break;
default:
console.log(`${number} is multiple of 3`)
}
}

Can a switch statement containing truthy values be written as an object literal lookup?

I have the following code displaying an image based on gamma values of the gyroscope. My first shot at it was to write a switch statement but having used object literals before I thought this could be a cleaner alternative. Is there any way to do this with the following code? Or any other cleaner solution?
switch (true) {
case (gamma <= -28):
view360.goToItem(0);
break;
case (gamma <= -24):
view360.goToItem(1);
break;
case (gamma <= -20):
view360.goToItem(2);
break;
case (gamma <= -16):
view360.goToItem(3);
break;
case (gamma <= -12):
view360.goToItem(4);
break;
case (gamma <= -8):
view360.goToItem(5);
break;
case (gamma <= -4):
view360.goToItem(6);
break;
case (gamma <= 0):
view360.goToItem(7);
break;
case (gamma <= 4):
view360.goToItem(8);
break;
case (gamma <= 8):
view360.goToItem(9);
break;
case (gamma <= 12):
view360.goToItem(10);
break;
case (gamma <= 16):
view360.goToItem(11);
break;
case (gamma <= 20):
view360.goToItem(12);
break;
case (gamma <= 24):
view360.goToItem(13);
break;
default:
view360.goToItem(13);
}
Your indexes are a function of the gamma, so you should write it as a function that captures that relationship. It looks like the relationship is simply (28 + gamma) / 4 with an additional check gamma is greater than 60. Since you are using inequalities to capture the in-between values, you need to divide by 31 and take the floor. This will allow both 3 and 4 to return 8 for example. So this should match your switches:
function getIndex(g) {
return g > 60 ? 13 : Math.floor((31 + g) / 4)
}
view360.goToItem(getIndex(gamma))
Not in this case, because you're using <= rather than =. Your whole method here would be better expressed with if and else - switch(true) is not really a switch.
Here's a switch you could convert to an object literal:
switch ( val ) {
case 'a': return 'hello';
case 'b': return 'goodbye';
}
Could be:
return { a: 'hello', b: 'goodbye' }[ val ];
Because the result of your switch (the argument to goToItem) is sequential (0, 1, 2...) you could use an array for this.
var gammaValues = [ -28, -24, -20, -16 /* etc */ ];
var idx = gammaValues.findIndex( value => gamma <= value );
if ( index !== -1 ) view360.goToItem( idx );
May be using map can help
const mapBreakpointToItem = {
-28: 0,
-24: 1,
...
};
Object.keys(mapBreakpointToItem).some((breakpoint) => {
if (gamma <= breakpoint) {
const item = mapBreakpointToItem[breakpoint];
view360.goToItem(item);
return true;
}
return false;
});
Or you can use math Math.floor((gamma + 31) / 4 for mapping breakpoints and items, but if something is changed its easier to change map object.

Switch case for comparing values

I want to use switch case for the values.
How can i compare values in case like <= or >=
case<240:
It gives error...
thanks.
Yes, this should be possible.
Here's an example:
var x = 5;
switch (true) {
case (x < 240):
alert("Less than 240");
break;
case (x >= 240):
alert("Greater than or equal to 240");
break;
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch
switch (true) {
case x < 240:
/* ... */
}
you have to compare with some value in this case and use space in between:
var x=100;
switch(true) {
case x < 100:
alert("Less than 100");
break;
case (x >= 100):
alert("greater or equal to 100");
break;
}

Operators in javascript switch case [duplicate]

This question already has answers here:
JavaScript: using a condition in switch case
(13 answers)
Closed 8 years ago.
Why does this return the default case:
var score=parseInt(3);
switch(score))
{
case(score<1):
alert('DUFF');
break;
case(score<5):
alert('AWESOME');
break;
default:
alert('NOPE');
break;
}
I've researched it but none of the solutions I've found work.
Because score having the integer value of 3 will never become boolean true or false, as (score < 1) is false and (score < 5) is true.
switch statement checks if the passed variable (or value) equals to one of the cases, i.e.:
switch (score) {
case 1:
// score is 1
break;
case 3:
// score is 3
break;
case true:
// score is true
break;
default:
// neither of above
}
What you are trying to achieve with switch statement can be done as follows:
switch (true) {
case (score < 1):
alert('DUFF');
break;
case (score < 5):
alert('AWESOME');
break;
default:
alert('NOPE');
}
This is a duplicate of javascript: using a condition in switch case
That being said, it would be better to just use if statements. You can use conditions (not just values) in your case statements, just by removing the parenthesis (see linked SO post above).
When you're not doing pattern matching, ifs are fine:
var score = parseInt(3);
if (score < 1) {
alert('DUFF');
} else if (score < 5) {
alert('AWESOME');
} else {
alert('NOPE');
}
This code becomes:
var score=3; // No need for parse here
switch(score)
{
case(false): /*score<1 */
alert('DUFF');
break;
case(true): /* score<5 */
alert('AWESOME');
break;
default:
alert('NOPE');
break;
}
You need:
var score= 3;
if (score<1) {
alert('DUFF');
} else if (score<5) {
alert('AWESOME');
} else {
alert('NOPE');
}

Categories

Resources