5

Is there a way to create multiple cases in a single Javascript switch statement?

In my code I receive the value of a field via jQuery.

Is it possible that one case checks for string regex and another for number of the same variable?

I am thinking along the lines of:

var field = $(this).val();
var msg;
switch (field) 
{
    case field.test('Yes'):

     msg = "FOO\n";
     break;

    case 10: 
     msg = "BAR\n";
     break;
}

Although I saw here: Switch statement for string matching in JavaScript

That the way to use switch on strings is by sending the switch statement a "true" value.

What would be the most concise (and correct!) way to achieve this?

Community
  • 1
  • 1
J00MZ
  • 675
  • 1
  • 10
  • 27
  • In my opinion an `if/else` would be the most concise and correct way, especially if there are only two cases. If there are additional cases then either add some `else if` branches as needed or include all of the number cases first in a `switch` and then do the regex tests in a `default`. You _can_ use `switch(true)` and then put whatever conditions you like for each `case`, indeed I've done that myself, but it only tends to make the code shorter when there are fall-through cases... – nnnnnn Aug 14 '13 at 11:00
  • as of now there are three but there may be more in the future, i would like the code to be easily extensible and if/else is not so... – J00MZ Aug 14 '13 at 11:05

3 Answers3

10

OK, compiling both answers above my code that worked and was most elegant IMO is:

var fieldVal = $(this).val();

var msg;

switch (true) 
{
  case /Yes/.test(fieldVal):
      msg = "FOO";
      break;
  case fieldVal > 10 :
      msg = "BAR";
      break;
}

this works as separate if statements since we are evaluating whether or not the case returns true but in a clearer and more concise way that could give us the option to add totally disparate test statements in one switch.

the reason it works is probably that the case expression evaluated is interpreted as a true or false value and then checked against the main - switch(true)

J00MZ
  • 675
  • 1
  • 10
  • 27
0

You can't the case need to single value, that's compared to switch expression, but you can put multiple cases to execute the same code:

switch (field) {
    case 'Yes':
    case 'yes':
    case 'YES':
        msg = "FOO\n";
        break;

    case 10: 
        msg = "BAR\n";
        break;
}

but in order to use test as case you can pass true to switch (I found that trick in some open source project):

switch (true) {
    case field.test('Yes'):
        msg = "FOO\n";
        break;
    case field == 10: 
        msg = "BAR\n";
        break;
}

but this is the same as if/else

jcubic
  • 61,973
  • 54
  • 229
  • 402
0

Note: you're using test() incorrectly, it's a method of a regex object, so you need /Yes/.test(field) rather than field.test('Yes'). Anyway...

If you've only got two cases as shown then I'd use an if/else/else if structure:

var field = $(this).val();
var msg;
if(/Yes/.test(field)) {
     msg = "FOO\n";
} else if (field === 10) { 
     msg = "BAR\n";
}

If you need to add additional cases I'd just add extra if else {} branches on the end.

If you have several specific numeric cases you might consider putting them in a switch with the regex tests in a default at the end:

switch (field) {
    case 10: 
        msg = "BAR\n";
        break;
    case 30:
        msg = "whatever\n";
        break;
    case 50:
        msg = "hi\n";
        break;
    default:
        if (/Yes/.test(field)) {
           msg = "FOO\n";
        else if (/No|N|False|/i.test(field)) {
           msg = "blah\n";
        }
        break;
}

The switch (true) option you alluded to in the question is really just a messier version of an if/else/else if, so it doesn't really make sense unless you have some fall-through cases:

switch(true)
    case /Yes/.test(field):
    case /Y/.text(field):
    case /Whatever/.text(field):
        msg = "FOO\n";
        break;
    case field == 10: 
        msg = "BAR\n";
        break;
}

...and even then an if with multiple conditions joined by || arguably just as tidy with appropriate newlines, and combining multiple regexes into a single one is probably a lot neater.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • just to clarify, i'm not checking whether the field value is a string or number but a specific number or string of a variable field. – J00MZ Aug 14 '13 at 11:53
  • Yes, isn't that the scenario covered in my answer? – nnnnnn Aug 14 '13 at 12:00