Link to home
Start Free TrialLog in
Avatar of jean ala
jean alaFlag for United Kingdom of Great Britain and Northern Ireland

asked on

switch statement in JavaScript

Hi
can we use And and Or in a switch statement in JavaScript?
also can AND and OR be used with swtich in other programming languages?
if yes can u show me an example. Thanks

 
SOLUTION
Avatar of XzKto
XzKto
Flag of Russian Federation image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Avatar of Lee
Lee
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sorry, you asked about javascript:
val=1;
switch(val) {
    case 1:
    case 2:
        alert('Key is 1 or 2.');
        break;
    default:
        alert( 'Key is not 1 or 2.');
}

Open in new window

will make same alerts if val=1 or val=2.
In Javascript, the closest you can achieve to an "OR" in a single case would be to string multiple cases together without putting a break in between them:

var color = "red";

switch (varName)
{
    case "red":
    case "orange":
    case "white": 
        alert("That's my favorite color too!");
        break;

    default: 
        alert("That color is OK.");
        break;
}

Open in new window


Some people prefer to string the cases in one statement for readability:

var color = "red";

switch (varName)
{
    case "red": case "orange": case "white": 
        alert("That's my favorite color too!");
        break;

    default: 
        alert("That color is OK.");
        break;
}

Open in new window


I'm not quite sure how an "AND" would be meaningful in a switch. Do you have an example of what you would like to achieve?
An OR can be effectively achived using the below code using what is called fall through case statements:
switch (varname)
{
    case "test" : case "test2" : case "test3":
        alert('test');
        break;
    case "test4" :
        alert('test4');
        break;
}

Open in new window


An AND would only be achived if I understand your requirement using a nested switch statement
So in the example below if varname = test or test2 or test3 and varname2 = Bob the alert will show test.
switch (varname)
{
    case "test" : case "test2" : case "test3":
        switch (varname2)
        {
             case "Bob":
                 alert('test');
                 break;
             case "Dave":
                 alert('test2');
                 break;
        }
        break;
    case "test4" :
        alert('test4');
        break;
}

Open in new window

Here's the javascript switch page on W3Schools: http://www.w3schools.com/js/js_switch.asp and looks just like @XzKto's PHP code.  It would be better to think of switch as a 'matching' function rather than AND or OR.

"can we use And and Or in a switch statement?"  The switch statement has to end up with a single value to match against the cases.  You can put any legitimate expression in the switch statement that evaluates to a single value.  It may be clearer to evaluate the expression to a value before the switch and just use the result.
Avatar of jean ala

ASKER

Thanks all
I know that but can we do something like :

switch (grade)
        {
             case >=90 and <=100 :
                 alert('A');
                 break;
VB is the only language I'm aware of that can do something similar to that. VB calls it a Select statement.
Select Case x
    Case 90 To 100

End Select

Open in new window

Comparisons evaluate to true or false (1 or 0).  That won't accomplish what you want (even if it was correct code).  You need to create a single value, not a range, that represents what you want before you use the switch/case statements.  If your application actually is about grades and ranges, you would be better off using 'if' statements with the right comparisons.
jean11,

Good that you know all those ways.

And no, you cannot do

switch (grade)
        {
             case >=90 and <=100 :
A switch is supposed to "switch" to the exact line (branch of code) upon resolution of a variable.  If you need and/or, then it isn't the right construct/keyword for you.
try :

switch (true)
{
    case ((grade >= 90)&&(grade <=100)):
        alert('A');
        break;
}
A variation on the VB (.NET) example I posted above (either should accomplish the same thing):
Select Case x
    Case Is >= 90, Is <= 100

End Select

Open in new window

Can you perhaps tell us why it must be a switch?

If is much more useful here

if (grade <90) {
  alert('you fail')
}
else if (grade <= 100) {
  alert("you have a grade between 90 and 100")
}
.
.
.
Like mplungjan's example, you shouldn't need an AND if you do your statements in order.
Start with the lowest value and move up. It will stop when it matches. If, elseif, else may be the best route for you.

Switch is made for distinct values usually string matching. For example after you assign letter grades, you could do a switch on the grade a,b,c,d,f and display a statement based on that grade.
Avatar of Proculopsis
Proculopsis


//I think you are after something like this:

var score = 98;
var grade = "";

switch ( threshold( score, 50, 60, 70, 80, 90, 100 ) ) {
  case 100: grade = "A"; break;
  case  90: grade = "B"; break;
  case  80: grade = "C"; break;
  case  70: grade = "D"; break;
  case  60: grade = "E"; break;
  case  50: grade = "F"; break;
}

alert( grade );

function threshold( score ) {
  var index = 0;
  while ( ++index < arguments.length ) {
    if ( score <= arguments[index] ) return arguments[index];
  }
}

Drat. Clever :) I was looking and looking at the MDC part here:

switch (expression) {
   case label1:

to see how that expression could be used.

However this WHOLE thing would look like this using if:


var score = 98;
function getGrade(score) {
  if (score <=  50) return "F";
  if (score <=  60) return "E";
  if (score <=  70) return "D";
  if (score <=  80) return "C";
  if (score <=  90) return "B";
  return "A";
}
alert(getGrade(score));

or perhaps

var score = 98;
var grades = {"F":50,"E":60,"D":70,"C":80,"B":90,"A":100 }
function getGrade(score) {
  for (var grade in grades) if (score <=  grades[grade]) return grade;
  return "undefined"
}
alert(getGrade(score));

Open in new window


// I think I like this slightly better:

var score = 98;
var grade = -1;

switch ( threshold( score, 40, 50, 60, 70, 80, 90 ) ) {
  case 40: grade++;
  case 50: grade++;
  case 60: grade++;
  case 70: grade++;
  case 80: grade++;
  case 90: grade++;
}

alert( ["A","B","C","D","E","F"][grade] );

function threshold( score ) {
  var index = arguments.length;
  while ( --index != 0 ) {
    if ( score > arguments[index] ) return arguments[index];
  }
}
No it isn't. Fails on 40 for example

// This is possibly a more elegant solution:

var grade = {
  a: { lower:  90, upper: 100 },
  b: { lower:  80, upper:  90 },
  c: { lower:  70, upper:  80 },
  d: { lower:  60, upper:  70 },
  e: { lower:  50, upper:  60 },
  f: { lower:   0, upper:  50 },
  scoring: function( score ) {
    var all = [ this.a, this.b, this.c, this.d, this.e, this.f ];
    var index = -1;
    while ( ++index != all.length ) {
      if ( score > all[index].lower && score <= all[index].upper ) {
        return all[index];
      }
    }
  }
};

switch ( grade.scoring( 97 ) ) {
  case grade.a: alert( "A" ); break;
  case grade.b: alert( "B" ); break;
  case grade.c: alert( "C" ); break;
  case grade.d: alert( "D" ); break;
  case grade.e: alert( "E" ); break;
  case grade.f: alert( "F" ); break;
}
That is in my opinion shooting sparrows with elephant guns. But I am sure jQuery people will love it.

I would stick to this one

var score = 98;
var grades = {"F":50,"E":60,"D":70,"C":80,"B":90,"A":100 }
function getGrade(score) {
  for (var grade in grades) if (score <=  grades[grade]) return grade;
  return "undefined"
}
alert(getGrade(score));

Open in new window


@mplungjan: the question was about the switch statement but ignoring that, this is neat and concise:

function gradeLetter( score ) {
  var grade = -1;
  while ( score < [ 90, 80, 70, 60, 50 ][++grade] );
  return String.fromCharCode( 65 + grade );
}
alert( gradeLetter( 97 ) );
Hmm, I do not agree about neat and concise.
It is clever but not understandable. If you want to add a "Z" grade, it would not be simple, and very hard for non-js gurus.

It's perfectly understandable but this isn't:

eval(unescape("4e756d6265722e70726f746f747970652e746f47726164653d66756e6374696f6e28297b7661722067726164653d2d313b7768696c6528746869733c5b39302c38302c37302c36302c35305d5b2b2b67726164655d293b72657475726e20537472696e672e66726f6d43686172436f64652836352b6772616465293b7d3b".replace(/(.{2})/g,"%$1")));

alert( (97).toGrade() );

Open in new window

it would not be simple, and very hard for non-js gurus.
I'll take on that role   = )

What in the heck is this doing:

while ( score < [ 90, 80, 70, 60, 50 ][++grade] )

Open in new window

it loops over the array created of [ 90, 80, 70, 60, 50 ]
indexed by grade starting at -1 and immediately counting up from 0 using the prefixed ++
comparing each value to score
I forgot JS uses square brackets for array initializers. Grazie!
The code as suggested here, creates the array each time so should not be used for large arrays

// Try this:

var percentage = 97;
var grade = "";

switch ( score( percentage, 50, 60, 70, 80, 90, 100 ) ) {
  case between( 90, 100 ): grade = "A"; break;
  case between( 80,  90 ): grade = "B"; break;
  case between( 70,  80 ): grade = "C"; break;
  case between( 60,  70 ): grade = "D"; break;
  case between( 50,  60 ): grade = "E"; break;
  case between(  0,  50 ): grade = "F"; break;
}

alert( grade );

function score( percentage ) {
  var lower = 0;
  var index = 1;
  do {
    var upper = arguments[index];
    if ( percentage <= upper ) {
        return between( lower, upper );
      }
      lower = upper;
  } while ( ++index < arguments.length )
}

function between( lower, upper ) {
  return JSON.stringify( { lower: lower, upper: upper } );
}
Now it is getting silly.

Where is the asker?
Split Proculopsis and me
@mplungjan why are your answers any more valid than anyone else's ?

Frankly I think my answer was the best solution, which is the problem we are not going to be able to decide who's answer is best without asker input
I'm on my mobile and there are 3 pages of answers - I know I answered this and that Proc too. Did not scroll through all answers. You obviously also think you should get points, no problem so far. I'll take a look later to see if I agree  
I personally like the answer that uses a if statement as thats how this really should be done. And the first/clearest of that type of answer was mplungjan. (I just agreed with him and explained a little).

To be fair, many people gave answers using switch that work which is what the question was for, but I feel that part of our duty is to steer people toward the best solution, which is "if", not "switch".
Ok, I reviewed your suggestions, Jacko - please show me which of your suggestions you think was the best. I did not see anyone I would use myself. Ever.

@Aaron: thanks for the kind words - I completely agree