关于javascript:根据值列表检查变量相等性

Check variable equality against a list of values

我检查一个变量,比如foo,是否与一些值相等。例如,

1
2
3
if( foo == 1 || foo == 3 || foo == 12 ) {
    // ...
}

关键是,对于这样一个微不足道的任务,它是相当多的代码。我想到了以下几点:

1
2
3
if( foo in {1: 1, 3: 1, 12: 1} ) {
    // ...
}

但这也不能完全吸引我,因为我必须为对象中的项提供冗余值。

有人知道一个正经的方法来对多个值进行相等检查吗?


您可以使用数组和indexOf

1
if ([1,3,12].indexOf(foo) > -1)


在ECMA2016中,您可以使用include方法。这是我见过的最干净的方式。(除IE(链接中包含polyfill)外,所有主要浏览器都支持此功能)

1
2
3
if([1,3,12].includes(foo)) {
    // ...
}


根据提供的答案,我得出以下结论:

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

它可以被称为:

1
2
3
if(foo.in(1, 3, 12)) {
    // ...
}

编辑:我最近遇到了这个"技巧",如果值是字符串并且不包含特殊字符,那么这个技巧很有用。因为特殊字符由于转义而变得难看,而且也更容易出错。

1
/foo|bar|something/.test(str);

更精确地说,这将检查精确的字符串,但对于简单的相等性测试来说,这又更为复杂:

1
/^(foo|bar|something)$/.test(str);


如果将L定义为

1
2
3
4
5
6
7
8
var L = function()
{
    var obj = {};
    for(var i=0; i<arguments.length; i++)
        obj[arguments[i]] = null;

    return obj;
};


这是很容易扩展和可读的:

1
2
3
4
5
6
7
8
9
10
11
12
13
switch (foo) {
    case 1:
    case 3:
    case 12:
        // ...
        break

    case 4:
    case 5:
    case 6:
        // something else
        break
}

但不一定容易。)


1
2
3
var a = [1,2,3];

if ( a.indexOf( 1 ) !== -1 ) { }

注意indexof不在核心ecmascript中。你需要一个IE的代码片段,可能还有其他不支持array.prototype.indexof的浏览器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(searchElement /*, fromIndex */)
  {
   "use strict";

    if (this === void 0 || 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)
        n = 0;
      else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0))
        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;
  };
}


此外,由于要检查结果的值都是唯一的,所以也可以使用set.prototype.has()。

1
2
3
4
5
6
7
var valid = [1, 3, 12];
var goodFoo = 3;
var badFoo = 55;

// Test
console.log( new Set(valid).has(goodFoo) );
console.log( new Set(valid).has(badFoo) );


如果可以访问下划线,则可以使用以下内容:

10

contains也曾在洛达什工作过(在v4之前),现在你必须使用includes

1
2
3
if (_.includes([1, 3, 12], foo)) {
  handleYellowFruit();
}

我喜欢这个被接受的答案,但是我认为它可以很好地接受数组,所以我将它扩展到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
}

var lucky = 7,
    more = [7, 11, 42];
lucky.isin(2, 3, 5, 8, more) //true

您可以通过将==更改为===来删除类型强制。


我只是使用jquery inarray函数和一个值数组来实现这一点:

1
2
3
4
5
6
myArr = ["A","B","C","C-"];

var test = $.inArray("C", myArr)  
// returns index of 2 returns -1 if not in array

if(test >= 0) // true

对于后代,您可能希望使用正则表达式作为替代。浏览器支持也相当不错(参考https://developer.mozilla.org/en-us/docs/web/javascript/reference/global_-objects/string/match_browser_兼容性)

试试这个

1
2
3
4
5
if (foo.toString().match(/^(1|3|12)$/)) {
    document.write('Regex me IN');
} else {
    document.write('Regex me OUT');
}