比较一个值和多个值的最佳方法是什么?

比较一个值和多个选项的 最漂亮的方法是什么?

我知道有很多方法可以做到这一点,但我正在寻找最整洁的。

我这样问是因为我希望这是可行的(事实并非如此,当你看着它的时候,这一点显而易见) :

if (foobar == (foo||bar) ) {
//do something
}
180340 次浏览

You can use a switch:

switch (foobar) {
case foo:
case bar:
// do something
}

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:
( https://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;
}
}

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.

(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.

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
}

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
}

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.

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.

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.