views:

255

answers:

7

Is there a better way to write the following conditional in javascript?

if ( value == 1 || value == 16 || value == -500 || value == 42.42 || value == 'something' ) {
  // blah blah blah
}

I hate having all of those logical ORs strung together. I'm wondering if there is some kind of shorthand.

Thanks!

+2  A: 

nope, that is the shorthand.

as an alternative, you can do a switch

switch (value) {
case 1 :
case 16 :
case -500 :
    ....
}

which is easier to manage if you need a lot of possible values, but actually your version is shorter anyway :)

oedo
If it's mixed you can cast value to a string and do string compares. Slower but possible. I also think this option is more .. readable than the `indexOf` option presented.
Matt S
oh you're right, i thought it was java not javascript :)
oedo
+5  A: 
var a = [1, 16, -500, 42.42, 'something'];
var value = 42;
if (a.indexOf(value) > -1){
// blah blah blah
}

Upd: Utility function sample as proposed in comments:

Object.prototype.in = function(){
  for(var i = 0; i < arguments.length; i++){
    if (this == arguments[i]) return true;
  }
  return false;
}

So you can write:

if (value.in(1, 16, -500, 42.42, 'something')){
// blah blah blah
}
Li0liQ
Just be aware that the `Array.prototype.indexOf` method is not available on IE.
CMS
@CMS Thanks for a valuable notice. Though, can be fixed at once. http://stackoverflow.com/questions/1744310/how-to-fix-array-indexof-in-javascript-for-ie-browsers
Li0liQ
This might make a good utility function to avoid making the if statement even more complex than the original. Just pass in an array of values and voila you have a shorthand syntax.
JohnFx
I'd strongly recommend against prototyping onto `Object`. Apart from the widespread nature of the namespace pollution, there is a high risk of breaking code that uses Objects as lookup mappings. Better to put this kind of utility method onto the `Array.prototype`. Also that allows you to use the method against things that do not inherit from `Object`, namely ‘host objects’ like DOM Nodes.
bobince
[Don't modify objects you don't own](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/), specially `Object.prototype`!
CMS
@Li0liQ, by the way, `in` is a reserved word, because it's a [Keyword](http://bclary.com/2004/11/07/#a-7.5.2). It shouldn't be used as identifier...
CMS
+4  A: 

You could extend the array object:

Array.prototype.contains = function(obj) {
  var i = this.length;
  while (i--) {
    if (this[i] == obj) {
      return true;
    }
  }
  return false;
}

Then if you store all those values in an array you could do something like MyValues.contains(value)

Prescott
If type coercion is not expected, I would recommend using `===` instead `==`, however IMO, with this approach, the best thing is to use the standard [`Array.prototype.indexOf`](https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/IndexOf) method, as [@Li0liQ](http://stackoverflow.com/questions/2932131/short-hand-for-chaining-logical-operators-in-javascript/2932166#2932166) mentions, is available *natively* on all browsers except IE.
CMS
I'm no javascript pro - good to know. Thanks
Prescott
A: 

switch is an acceptable choice. You can also use a map, depending on the complexity of the problem (assuming you have more than you put in your example).

var accept = { 1: true, 16: true, '-500': true, 42.42: true, something: true };
if (accept[value]) {
  // blah blah blah
}

accept could be generated progamatically from an array of course. Depends really on how much you plan on using this pattern. :/

jimbojw
A: 

Well, you could use a switch statement...

switch (value) {
  case 1    : // blah
              break;
  case 16   : // blah
              break;
  case -500 : // blah
              break;
  case 42.42: // blah
              break;
  case "something" : // blah
                     break;
}

If you're using JavaScript 1.6 or greater, you can use the indexOf notation on an array:

if ([1, 16, -500, 42.42, "something"].indexOf(value) !== -1) {
   // blah
}

And for the ultimate in hackiness, you can coerce the values to strings (this works for all browsers):

if ("1,16,-500,42.42,something".indexOf(value) !== -1) {
   // blah
}
Matt Brock
A: 
var value= -55;
switch(value){
    case 1: case 16: case -55: case 42.5: case 'something': 
        alert(value); break;        

}
kennebec
A: 

In an effort to make yet another way of doing it...

if (/^(1|16|-500|42.42|something)$/.test(value)) {
  // blah blah blah
}

No need to extend array prototypes or anything, just use a quick regexp to test the value!

gnarf