Shorter version of switch statement for complex cases - javascript

It is possible to make shorter version of this statement? I know that there is shorthand for switch statement if cases are like 1,2,3 etc.
var direction = pos[i].direction;
switch (true) {
case (direction >= 0 && direction < 22):
graphic = "/img/0.png"
break;
case (direction >= 22 && direction < 45):
graphic = "/img/225.png"
break;
case (direction >= 45 && direction < 67):
graphic = "/img/450.png"
break;
case (direction >= 67 && direction < 90):
graphic = "/img/675.png"
break;
default:
graphic = "/img/0.png"
break;
}

You could omit the first check, because the value is already checked before.
switch (true) {
case direction < 22:
graphic = "/img/0.png";
break;
case direction < 45:
graphic = "/img/225.png";
break;
case direction < 67:
graphic = "/img/450.png";
break;
case direction < 90:
graphic = "/img/675.png";
break;
default:
graphic = "/img/0.png";
break;
}

You should use if else because you have conditions ready with you.so no need to use switch case.

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

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

Switch statement for a range not working

I am using a switch case in javascript to find a range, but its not working. Have I done something wrong?
function mapPriceRange(value){
var range = '';
switch(value)
{
case (value >= 0 && value <= 25):
range = '0_25';
break;
case (value >= 25 && value <= 40):
range = '25_40';
break;
case (value >= 40 && value <= 60):
range = '40_60';
break;
case (value >= 60 && value <= 100):
range = '60_100';
break;
case (value >= 100 && value <= 150):
range = '100_150';
break;
case (value >= 150 && value <= 200):
range = '150_200';
break;
case (value >= 200 && value <= 300):
range = '200_300';
break;
case (value >= 300 && value <= 500):
range = '300_500';
break;
case (value >= 500 && value <= 1000):
range = '500_1000';
}
return range;
}
console.log(mapPriceRange(500));
I am always getting an empty string.
Just replace switch(value) to switch(true) and it should work. See jsFiddle.
use below code
function checkRange(x, n, m) {
if (x >= n && x <= m) { return x; }
else { return !x; }
}
var x = 5;
function mapPriceRange(value){
var range = '';
switch(value)
{
case checkRange(x, 0, 25):
range = '0_25';
break;
case checkRange(x, 25, 40):
range = '25_40';
break;
case checkRange(x, 40, 60):
range = '40_60';
break;
case checkRange(x, 60, 100):
range = '60_100';
break;
case checkRange(x, 100, 150):
range = '100_150';
break;
case checkRange(x, 150, 200):
range = '150_200';
break;
case checkRange(x, 200, 300):
range = '200_300';
break;
case checkRange(x, 300, 500):
range = '300_500';
break;
case checkRange(x, 500, 1000):
range = '500_1000';
}
return range;
}
console.log(mapPriceRange(500));
Switch cases in Javascript only with strings. They coerce any input they receive in either the switch or in the case to string before comparing it. Hence, your value.toString() is getting compared to the "true" and "false" strings in the various cases, which is returning false in every case.
Using an ifElse ladder is the best way around it and refer to any of the other answers for a possible workaround which relies on returning either value.toString() or switch over "true" instead of value.

JavaScript: using a condition in switch case

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

Using mathematics in a switch statement case? [duplicate]

Am I writing the correct switch case with conditions?
var cnt = $("#div1 p").length;
alert(cnt);
switch (cnt) {
case (cnt >= 10 && cnt <= 20):
alert('10');
break;
case (cnt >= 21 && cnt <= 30):
alert('21');
break;
case (cnt >= 31 && cnt <= 40):
alert('31');
break;
default:
alert('>41');
}
For some reason, the alert does not occur when the conditions are matched!
A switch works by comparing what is in switch() to every case.
switch (cnt) {
case 1: ....
case 2: ....
case 3: ....
}
works like:
if (cnt === 1) ...
if (cnt === 2) ...
if (cnt === 3) ...
Therefore, you can't have any logic in the case statements.
switch (cnt) {
case (cnt >= 10 && cnt <= 20): ...
}
works like
if (cnt === (cnt >= 10 && cnt <= 20)) ...
and that's just nonsense. :)
Use if () { } else if () { } else { } instead.
You should not use switch for this scenario. This is the proper approach:
var cnt = $("#div1 p").length;
alert(cnt);
if (cnt >= 10 && cnt <= 20)
{
alert('10');
}
else if (cnt >= 21 && cnt <= 30)
{
alert('21');
}
else if (cnt >= 31 && cnt <= 40)
{
alert('31');
}
else
{
alert('>41');
}
This should work with this :
var cnt = $("#div1 p").length;
switch (true) {
case (cnt >= 10 && cnt <= 20):
alert('10');
break;
case (cnt >= 21 && cnt <= 30):
alert('21');
break;
case (cnt >= 31 && cnt <= 40):
break;
default:
alert('>41');
}
Something I came upon while trying to work a spinner was to allow for flexibility within the script without the use of a ton of if statements.
Since this is a simpler solution than iterating through an array to check for a single instance of a class present it keeps the script cleaner. Any suggestions for cleaning the code further are welcome.
$('.next').click(function(){
var imageToSlide = $('#imageSprite'); // Get id of image
switch(true) {
case (imageToSlide.hasClass('pos1')):
imageToSlide.removeClass('pos1').addClass('pos2');
break;
case (imageToSlide.hasClass('pos2')):
imageToSlide.removeClass('pos2').addClass('pos3');
break;
case (imageToSlide.hasClass('pos3')):
imageToSlide.removeClass('pos3').addClass('pos4');
break;
case (imageToSlide.hasClass('pos4')):
imageToSlide.removeClass('pos4').addClass('pos1');
}
}); `
What you are doing is to look for (0) or (1) results.
(cnt >= 10 && cnt <= 20) returns either true or false.
--edit--
you can't use case with boolean (logic) experessions. The statement cnt >= 10 returns zero for false or one for true. Hence, it will we case(1) or case(0) which will never match to the length.
--edit--
function date_conversion(start_date){
var formattedDate = new Date(start_date);
var d = formattedDate.getDate();
var m = formattedDate.getMonth();
var month;
m += 1; // JavaScript months are 0-11
switch (m) {
case 1: {
month="Jan";
break;
}
case 2: {
month="Feb";
break;
}
case 3: {
month="Mar";
break;
}
case 4: {
month="Apr";
break;
}
case 5: {
month="May";
break;
}
case 6: {
month="Jun";
break;
}
case 7: {
month="Jul";
break;
}
case 8: {
month="Aug";
break;
}
case 9: {
month="Sep";
break;
}
case 10: {
month="Oct";
break;
}
case 11: {
month="Nov";
break;
}
case 12: {
month="Dec";
break;
}
}
var y = formattedDate.getFullYear();
var now_date=d + "-" + month + "-" + y;
return now_date;
}
Switch case is every help full instead of if else statement :
switch ($("[id*=btnSave]").val()) {
case 'Search':
saveFlight();
break;
case 'Update':
break;
case 'Delete':
break;
default:
break;
}
Ok it is late but in case you or someone else still want to you use a switch or simply have a better understanding of how the switch statement works.
What was wrong is that your switch expression should match in strict comparison one of your case expression. If there is no match it will look for a default. You can still use your expression in your case with the && operator that makes Short-circuit evaluation.
Ok you already know all that. For matching the strict comparison you should add at the end of all your case expression && cnt.
Like follow:
switch(mySwitchExpression)
case customEpression && mySwitchExpression: StatementList
.
.
.
default:StatementList
var cnt = $("#div1 p").length;
alert(cnt);
switch (cnt) {
case (cnt >= 10 && cnt <= 20 && cnt):
alert('10');
break;
case (cnt >= 21 && cnt <= 30 && cnt):
alert('21');
break;
case (cnt >= 31 && cnt <= 40 && cnt):
alert('31');
break;
default:
alert('>41');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="div1">
<p> p1</p>
<p> p2</p>
<p> p3</p>
<p> p3</p>
<p> p4</p>
<p> p5</p>
<p> p6</p>
<p> p7</p>
<p> p8</p>
<p> p9</p>
<p> p10</p>
<p> p11</p>
<p> p12</p>
</div>

Categories

Resources