63

Is there an easier way to determine if a variable is equal to a range of values, such as:

if x === 5 || 6 

rather than something obtuse like:

if x === 5 || x === 6

?

OfirD
  • 9,442
  • 5
  • 47
  • 90
Adam Templeton
  • 4,467
  • 7
  • 27
  • 39
  • 2
    Why do you consider the latter obtuse? – Alnitak Aug 24 '12 at 20:42
  • 1
    Because I need to write some code that checks if a variable has one of 20 values, namely, if x = "New York" || "Austin" || "Alberta", etc. – Adam Templeton Aug 24 '12 at 20:56
  • 7
    @AdamTempleton: Either put all your values in an array, and then use `indexOf`, or you can also use a regex `/^(New York|Austin|Alberta)$/.test(x)`. – João Silva Aug 24 '12 at 21:02
  • 1
    @AdamTempleton in which case you should rewrite your question to say so. You specifically say _two_ in the subject. – Alnitak Aug 24 '12 at 22:32
  • Use s = new Set([5, 6]); s.has(x);. Not sure why I can't anser this question. – Denly Jan 09 '18 at 06:27
  • While the answers are ultimately the same, the intent of the questions are very different, and I believe that pointing people to a question about arrays when they ask about how to check for multiple values does a disservice to askers. I'd rather point them to this question. – Heretic Monkey Nov 03 '20 at 17:27
  • [javascript - Check variable equality against a list of values - Stack Overflow](https://stackoverflow.com/questions/4728144/check-variable-equality-against-a-list-of-values) is a better duplicate. – user202729 Jan 26 '21 at 15:55

8 Answers8

90

You can stash your values inside an array and check whether the variable exists in the array by using [].indexOf:

if([5, 6].indexOf(x) > -1) {
  // ...
}

If -1 is returned then the variable doesn't exist in the array.

Roy
  • 7,811
  • 4
  • 24
  • 47
Yoshi
  • 54,081
  • 14
  • 89
  • 103
  • 10
    This does not work in IE < 9. See [MDN's Array#indexOf Compatibility section](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf#Compatibility) for code that you can insert to actually make it work in IE. However, unless you are using this in several places, it would probably be faster just to use `a == 1 || a == 2`. – Reid Aug 24 '12 at 21:55
  • 4
    Alternatively, if you are using a JS framework, both MooTools and Prototype ensure Array#indexOf exists. jQuery, on the other hand, provides its own implementation in the form of [`$.inArray`](http://api.jquery.com/jQuery.inArray/). I'm not familiar with any other frameworks, but I'm sure they all include such functionality in some manner. – Reid Aug 24 '12 at 22:00
  • A bit more description of the code would have been nice. – Julix Oct 14 '16 at 00:38
  • 2
    And now we have i.e. ```['a','b'].includes('a')``` – Devmaleeq Jul 26 '21 at 08:03
24

Depends on what sort of test you're performing. If you've got static strings, this is very easy to check via regular expressions:

if (/^[56ab]$/.test(item)) {
//-or-
if (/^(foo|bar|baz|fizz|buzz)$/.test(item)) {
    doStuff();
} else {
    doOtherStuff();
}

If you've got a small set of values (string or number), you can use a switch:

switch (item) {
case 1:
case 2:
case 3:
    doStuff();
    break;
default:
    doOtherStuff();
    break;
}

If you've got a long list of values, you should probably use an array with ~arr.indexOf(item), or arr.contains(item):

vals = [1,3,18,3902,...];
if (~vals.indexOf(item)) {
    doStuff();
} else {
    doOtherStuff();
}

Unfortunately Array.prototype.indexOf isn't supported in some browsers. Fortunately a polyfill is available. If you're going through the trouble of polyfilling Array.prototype.indexOf, you might as well add Array.prototype.contains.

Depending on how you're associating data, you could store a dynamic list of strings within an object as a map to other relevant information:

var map = {
    foo: bar,
    fizz: buzz
}
if (item in map) {
//-or-
if (map.hasOwnProperty(item)) {
    doStuff(map[item]);
} else {
    doOtherStuff();
}

in will check the entire prototype chain while Object.prototype.hasOwnProperty will only check the object, so be aware that they are different.

Community
  • 1
  • 1
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
17

It's perfectly fine. If you have a longer list of values, perhaps you can use the following instead:

if ([5,6,7,8].indexOf(x) > -1) {
}
João Silva
  • 89,303
  • 29
  • 152
  • 158
7

Yes. You can use your own function. This example uses .some:

var foo = [ 5, 6 ].some(function(val) {
     return val === x;
   });

foo; // true
David G
  • 94,763
  • 41
  • 167
  • 253
3

This is what I've decided to use:

Object.prototype.isin = function() {
    for(var i = arguments.length; i--;) {
        var a = arguments[i];
        if(a.constructor === Array) {
            for(var j = a.length; j--;)
                if(a[j] == this) return true;
        }
        else if(a == this) return true;
    }
    return false;
}

You would use it like this:

var fav   = 'pear',
    fruit = ['apple', 'banana', 'orange', 'pear'],
    plu   = [4152, 4231, 3030, 4409];

if (fav.isin(fruit, plu, 'eggs', 'cheese')) {
    //do something cool
}

The advantages are:

  • it works in IE < 9;
  • it reads naturally from left to right;
  • you can feed it arrays or separate values.

If you don't want to allow type coercion (indexOf does not), change the two == to ===. As it stands:

fav = "4231";
plu.indexOf(fav) //-1
fav.isin(plu)    //true
Greg Perham
  • 1,835
  • 1
  • 17
  • 26
2

no, there might be a few tricks that are case specific but in general i write code like this:

if (someVariable === 1 ||
    someVariable === 2 ||
    someVariable === 7 ||
    someVariable === 12 ||
    someVariable === 14 ||
    someVariable === 19) {

    doStuff();
    moreStuff();

} else {
    differentStuff();
}
orlp
  • 112,504
  • 36
  • 218
  • 315
ckozl
  • 6,751
  • 3
  • 33
  • 50
0

The simple answer is no. You can use a switch statement, which is easier to read if you are comparing a lot of string values, but using it for two values wouldn't look any better.

monitorjbl
  • 4,280
  • 3
  • 36
  • 45
-2

[Edit] this seems to work, but as Dan pointed out, it is actually a false positive. Do not use this method. I leave it here for educational purposes.

Easiest way I know :

a = [1,2,3,4,5];

if(3 in a) alert("true"); // will alert true

Tested in Chrome console. Not sure if it works in other browsers.

Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63
  • That example works by accident. Try `3 in [1, 3]` - it will return `false` because there is no element *with the index 3* in the array `[1, 3]`. For that matter, `3 in ['a', 'b', 'c', 'd']` will return true. – Dan Dascalescu Sep 10 '15 at 11:21
  • 2
    Damn, so it's a false positive. Thanks for that. – Jeremy Thille Sep 10 '15 at 15:46