tags:

views:

161

answers:

6

Is there a simpler way to rewrite the following condition in JavaScript?

if ((x == 1) || (x == 3) || (x == 4) || (x == 17) || (x == 80)) {...}
+5  A: 
switch (x) {
    case 1:
    case 3:
    case 4:
    case 17:
    case 80:
        //code
        break;
    default:
        //code
}
Yongho
not exactly simpler, but a nice alternative, and good use of not using a break, which btw you forgot to put after the code in `case 80:`
thecoshman
and you need the break in the default case
BritishDeveloper
I've made the edits you suggested. Thanks!
Yongho
@BritishDeveloper the default clause doesn't require a break, as there cannot be any cases after the default. For example, see http://www.w3schools.com/js/js_switch.asp
cmptrgeekken
@cmptrgeekken true - i had my c# eyes in
BritishDeveloper
+12  A: 

You could use an array of valid values and test it with indexOf:

if ([1, 3, 4, 17, 80].indexOf(x) != -1)

Edit    Note that indexOf was just added in ECMAScript 5 and thus is not implemented in every browser. But you can use the following code to add it if missing:

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

Or, if you’re already using a JavaScript framework, you can also use its implementation of that method.

Gumbo
Great, this is what I was looking for ! Thanks !
Misha Moroshko
+1... This is the neatest. The `in` operator does not work correctly for arrays, as you suggested: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/in_Operator
Daniel Vassallo
+1 innovative! ugly but interesting
BritishDeveloper
add a notice about indexOf not working in Explorer
stereofrog
@sterofrog: You can add indexOf to older browsers: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/indexOf
Daniel Vassallo
@Daniel: yes, this should be added to the answer, for gooogler's benefit
stereofrog
Bear in mind that setting Array prototype members breaks the for (i in array) construct, as those prototype members will show up as items of every array. If Array prototype members are set (e.g. with this, by mootools, etc.), you have to iterate over the members with `for var i = 0; i < array.length; i++` , or use a framework function that handles it for you (e.g. jQuery.each()).
Joey Adams
@Joey Adams: `for … in` is for object properties and not array keys. *Always* use a the standard ranging `for` loop for array iteration. (jQuery does that too.)
Gumbo
A: 

many options

if ([0, 1, 3, 4, 17, 80].indexOf(x) > 0)

if(/^(1|3|4|17|80)$/.test(x))

if($.inArray(x, [1, 3, 4, 17, 80]) 

another one, based on Ed's answer

function list() {
    for (var i = 0, o = {}; i < arguments.length; i++)
        o[arguments[i]] = '';
    return o;
}


if(x in list(1, 3, 4, 17, 80))...
stereofrog
JavaScript’s array index starts with 0.
Gumbo
@Gumbo: really? ;/
stereofrog
@stereofrog: Yes: `[0, 1, 3, 4, 17, 80].indexOf(0) === 0`.
Gumbo
@Gumbo: and...?
stereofrog
@stereofrog: so, I think `if ([0, 1, 3, 4, 17, 80].indexOf(x) > 0)` needs to be `if ([0, 1, 3, 4, 17, 80].indexOf(x) >= 0)`
Daniel Vassallo
@Daniel Vassallo, this would return 'true' for x=0, which is wrong
stereofrog
@stereofrog: Ok, I see that you've added an extra element in the array. But why not `if ([1, 3, 4, 17, 80].indexOf(x) != -1)`?
Daniel Vassallo
@Daniel Vassallo - lol, downvoting me because _you_ cannot read!!!
stereofrog
@stereofrog: I promise I didn't downvote. But I still did not get why you prefer to add a fictitious first element.
Daniel Vassallo
A: 

You can optimize your own example and get rid of a few characters, making it easier on the eyes..:

if (x == 1 || x == 3 || x == 4 || x == 17 || x == 80) { ... }
roosteronacid
+2  A: 

This is a little function I found somewhere on the web:

function oc(a) {
    var o = {};
    for (var i = 0; i < a.length; i++) {
        o[a[i]] = '';
    }
    return o;
}

Used like this:

if (x in oc(1, 3, 4, 17, 80)) {...}

I'm using it for strings myself; haven't tried with numbers, but I guess it would work.

Ed
nice one, and can be even nicer without extra [..]'s (see http://stackoverflow.com/questions/2630364/reduce-multiple-ors-in-if-statement-in-javascript/2630444#2630444)
stereofrog
Updated my answer.
Ed
+1  A: 

a regular expression test uses the string value of x:

if(/^[134]|17|80$/.test(x)){/*...*/}
kennebec