This is a seemingly simple programming task that we deal with everyday. Here’s the situation:
- 1] You have a string in JavaScript, like
var fruit = ''
. - 2] You need to know if that string is equal to one of multiple values, say
"banana"
or"lemon"
[because the yellow fruits need special yellow fruit processing or something].
Most people accomplish this by doing two string comparisons connected by a logical OR, which looks like this:
if [fruit == 'banana' || fruit == 'lemon'] {
handleYellowFruit[];
}
Which works fine,
but is a bit clunky. I mean, you have to type fruit ==
two whole times. It also doesn’t scale well. Say your fruit processing product takes off and you need to support more fruit, now you have this:
if [fruit == 'banana' || fruit == 'lemon' || fruit == 'mango' || fruit == 'pineapple'] {
handleYellowFruit[];
}
This is getting a bit ugly. Let’s look at some other ways of accomplishing the same check.
Switch
The switch statement can be used to achieve the same ends:
switch [fruit] {
case 'banana':
case 'lemon':
case 'mango':
case 'pineapple':
handleYellowFruit[];
}
This approach would be helpful if we have to handle for multiple classifications of fruits. But for one check it’s a lot of typing and takes up a lot of space.
Array Based
ECMAScript 5 introduced an indexOf
method on Array.prototype
[docs]. We can use this to create an array on the fly, then see whether the value matches one of the values in the array:
if [['banana', 'lemon', 'mango', 'pineapple'].indexOf[fruit] >= 0] {
handleYellowFruit[];
}
This is better, but still not ideal. Understanding this code relies on the
reader knowing that the indexOf
method returns -1
, which is not necessarily common knowledge.
Also, because Array.prototype.indexOf
was added in ECMAScript 5, it’s not present in IE -1;
};
This allows the check to be:
if [['banana', 'lemon', 'mango', 'pineapple'].contains[fruit]] {
handleYellowFruit[];
}
Regular Expressions
An often overlooked means of performing this check is to use regular expressions via String.prototype.match
[docs].
if [fruit.match[/^[banana|lemon|mango|pineapple]$/]] {
handleYellowFruit[];
}
This check clearly requires the least amount of typing. It is also the most flexible as you can easily alter things like case sensitivity, special character handling, white space, etc. This will work in all browsers and you don’t have to worry about messing with the native prototypes.
While this is the most powerful option, it comes at a cost of being less
readable. I had to look up the ^
[match at the beginning of input] and $
[match at the end of input] characters when writing this post.
Whats the prettiest way to compare one value against multiples options?
I know there are loads of ways of doing this, but I'm looking for the neatest.
i ask because i'd hoped this was workable [it isn't, quite obviously when you look at it]:
if [foobar == [foo||bar] ] {
//do something
}
isherwood
54.2k15 gold badges105 silver badges147 bronze badges
asked Feb 2, 2012 at 23:09
thelastshadowthelastshadow
3,2653 gold badges34 silver badges35 bronze badges
3
Don't try to be too sneaky, especially when it needlessly affects performance. If you really have a whole heap of comparisons to do, just format it nicely.
if [foobar === foo ||
foobar === bar ||
foobar === baz ||
foobar === pew] {
//do something
}
answered Feb 2, 2012 at 23:35
5
What i use to do, is put those multiple values in an array like
var options = [foo, bar];
and then, use indexOf[]
if[options.indexOf[foobar] > -1]{
//do something
}
for prettiness:
if[[foo, bar].indexOf[foobar] +1]{
//you can't get any more pretty than this :]
}
and for the older browsers:
[ //developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/IndexOf ]
if [!Array.prototype.indexOf] {
Array.prototype.indexOf = function [searchElement /*, fromIndex */ ] {
"use strict";
if [this == null] {
throw new TypeError[];
}
var t = Object[this];
var len = t.length >>> 0;
if [len === 0] {
return -1;
}
var n = 0;
if [arguments.length > 0] {
n = Number[arguments[1]];
if [n != n] { // shortcut for verifying if it's NaN
n = 0;
} else if [n != 0 && n != Infinity && n != -Infinity] {
n = [n > 0 || -1] * Math.floor[Math.abs[n]];
}
}
if [n >= len] {
return -1;
}
var k = n >= 0 ? n : Math.max[len - Math.abs[n], 0];
for [; k < len; k++] {
if [k in t && t[k] === searchElement] {
return k;
}
}
return -1;
}
}
answered Feb 2, 2012 at 23:12
7
Since nobody has added the obvious solution yet which works fine for two comparisons, I'll offer it:
if [foobar === foo || foobar === bar] {
//do something
}
And, if you have lots of values [perhaps hundreds or thousands], then I'd suggest making a Set as this makes very clean and simple comparison code and it's fast at runtime:
// pre-construct the Set
var tSet = new Set[["foo", "bar", "test1", "test2", "test3", ...]];
// test the Set at runtime
if [tSet.has[foobar]] {
// do something
}
For pre-ES6, you can get a Set polyfill of which there are many. One is described in this other answer.
answered Feb 2, 2012 at 23:18
jfriend00jfriend00
652k90 gold badges925 silver badges928 bronze badges
4
You can use a switch:
switch [foobar] {
case foo:
case bar:
// do something
}
answered Feb 2, 2012 at 23:12
GuffaGuffa
673k108 gold badges718 silver badges991 bronze badges
0
Just for kicks, since this Q&A does seem to be about syntax microanalysis, a tiny tiny modification of André Alçada Padez's suggestion[s]:
[and of course accounting for the pre-IE9 shim/shiv/polyfill he's included]
if [~[foo, bar].indexOf[foobar]] {
// pretty
}
answered Feb 13, 2013 at 10:27
lucideerlucideer
3,78424 silver badges31 bronze badges
1
Why not using indexOf
from array like bellow?
if [[foo, bar].indexOf[foobar] !== -1] {
// do something
}
Just plain Javascript, no frameworks or libraries but it will not work on IE < 9.
answered Jun 7, 2013 at 8:54
Ionică BizăuIonică Bizău
104k81 gold badges273 silver badges456 bronze badges
2
[foobar == foo || foobar == bar]
otherwise if you are comparing expressions based only on a single integer, enumerated value, or String object
you can use switch. See The switch Statement. You can also use the method suggested by André Alçada Padez. Ultimately what you select will need to depend on the details of what you are doing.
david
17.4k4 gold badges42 silver badges57 bronze badges
answered Feb 2, 2012 at 23:21
JamieSeeJamieSee
12.4k2 gold badges30 silver badges47 bronze badges
5
The switch method [as mentioned by Guffa] works very nicely indeed. However, the default warning settings in most linters will alert you about the use of fall-through. It's one of the main reasons I use switches at all, so I pretty much ignore this warning, but you should be aware that the using the fall-through feature of the switch statement can be tricky. In cases like this, though - I'd go for it.
answered Feb 25, 2014 at 11:43
NinjaToolNinjaTool
531 silver badge5 bronze badges
0
I like the pretty form of testing indexOf with an array, but be aware, this doesn't work in all browsers [because Array.prototype.indexOf is not present in old IExplorers].
However, there is a similar way by using jQuery with the $.inArray[] function :
if [$.inArray[field, ['value1', 'value2', 'value3']] > -1] {
alert['value ' + field + ' is into the list'];
}
It could be better, so you should not test if indexOf exists.
Be careful with the comparison [don't use == true/false], because $.inArray returns the index of matching position where the value has been found, and if the index is 0, it would be false when it really exist into the array.
answered Mar 25, 2015 at 9:56
1