根据值列表检查变量相等性

时间:2011-01-18 19:27:16

标签: javascript

我正在检查变量,比如说foo,与多个值相等。例如,

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

关键是这个琐碎任务的代码相当多。我想出了以下内容:

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

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

有没有人知道对多个值进行相等检查的正确方法?

15 个答案:

答案 0 :(得分:155)

您可以使用数组和indexOf

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

答案 1 :(得分:76)

在ECMA2016中,您可以使用includes方法。这是我见过的最干净的方式。 (由所有主流浏览器支持,IE除外(Polyfill在链接中)

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

答案 2 :(得分:19)

使用提供的答案,我最终得到以下内容:

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

可以这样称呼:

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

编辑:我最近遇到了这个'技巧',如果值是字符串且不包含特殊字符,则非常有用。对于特殊字符而言,由于转义而变得丑陋,并且由于这一点而更容易出错。

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

更确切地说,这将检查确切的字符串,但对于简单的相等测试再次更复杂:

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

答案 3 :(得分:7)

如果您将if(foo in L(10,20,30))定义为

,则可以写L
var L = function()
{
    var obj = {};
    for(var i=0; i<arguments.length; i++)
        obj[arguments[i]] = null;

    return obj;
};

答案 4 :(得分:6)

var a = [1,2,3];

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

请注意,indexOf不在核心ECMAScript中。您需要为IE以及可能不支持Array.prototype.indexOf的其他浏览器提供一个代码段。

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;
  };
}

答案 5 :(得分:6)

这很容易扩展和阅读:

switch (foo) {
    case 1:
    case 3:
    case 12:
        // ...
        break

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

但不一定更容易:)

答案 6 :(得分:1)

我喜欢接受的答案,但是认为它也可以使它能够接受数组,所以我把它扩展到了这个:

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

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

答案 7 :(得分:1)

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

if (_.contains([1, 3, 12], foo)) {
  // ...
}

contains过去也曾在Lodash工作(在V4之前),现在你必须使用includes

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

答案 8 :(得分:1)

此外,由于您检查结果的值都是唯一的,因此您也可以使用Set.prototype.has()

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) );

答案 9 :(得分:1)

现在您可能有更好的解决方案来解决此问题,但是我更喜欢采用其他方式。

const arr = [1,3,12]
if( arr.includes(foo)) { // it will return true if you `foo` is one of array values else false
  // code here    
}

在需要同时检查索引的indexOf check上,我更喜欢上述解决方案。

includes docs

if ( arr.indexOf( foo ) !== -1 ) { }

答案 10 :(得分:0)

我只是使用jQuery inArray函数和一组值来完成此任务:

myArr = ["A", "B", "C", "C-"];

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

if(test >= 0) // true

答案 11 :(得分:0)

这是一个辅助助手功能:

const letters = ['A', 'B', 'C', 'D'];

function checkInList(arr, val) {
  return arr.some(arrVal => val === arrVal);
}

checkInList(letters, 'E');   // false
checkInList(letters, 'A');   // true

More info here...

答案 12 :(得分:0)

对于您经常比较的更大的值列表,首先构造一个 Set 并使用 Set#has 进行恒定时间检查可能比运行的 Array#includes 更好在线性时间内。

const values = new Set([1, 2, 12]);
if(values.has(foo)){
   // do something
}

答案 13 :(得分:0)

使用 ES6 语法,您可以:

Object.prototype.in = function (...args) {
  return args.includes(this.valueOf());
}

顺便说一下,它还检查了深度相等性。需要 valueOf() 方法,因为 this 是一个对象。

答案 14 :(得分:-2)

对于后代,您可能希望使用正则表达式作为替代。非常好的浏览器支持(参考https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match#Browser_compatibility

试试这个

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