确定字符串是否在JavaScript中列表中

Determine if string is in list in JavaScript

在SQL中,我们可以看到字符串是否在这样的列表中:

1
Column IN ('a', 'b', 'c')

在JavaScript中有什么好方法可以做到这一点?这样做太笨拙了:

1
2
3
if (expression1 || expression2 || str === 'a' || str === 'b' || str === 'c') {
   // do something
}

我不确定这方面的表现或清晰度:

1
2
3
if (expression1 || expression2 || {a:1, b:1, c:1}[str]) {
   // do something
}

或者可以使用开关功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var str = 'a',
   flag = false;

switch (str) {
   case 'a':
   case 'b':
   case 'c':
      flag = true;
   default:
}

if (expression1 || expression2 || flag) {
   // do something
}

但这是一个可怕的混乱。有什么想法吗?

在这种情况下,我必须使用Internet Explorer 7,因为它用于企业内部网页面。因此,如果没有语法糖,['a', 'b', 'c'].indexOf(str) !== -1就不能正常工作。


你可以打电话给indexOf

1
2
3
if (['a', 'b', 'c'].indexOf(str) >= 0) {
    //do something
}


ECMAScript 6

如果您使用的是ES6,那么可以构造一个项目数组,并使用includes

1
['a', 'b', 'c'].includes('b')

这比indexOf有一些内在的好处,因为它可以适当地测试列表中是否存在NaN,并且可以匹配缺少的数组元素,如[1, , 2]中的中间元素到undefined中的元素。includes也适用于Javascript类型的数组,如Uint8Array

没有数组

您可以将新的isInList属性添加到字符串中,如下所示:

1
2
3
4
5
6
7
8
9
if (!String.prototype.isInList) {
   String.prototype.isInList = function() {
      let value = this.valueOf();
      for (let i = 0, l = arguments.length; i < l; i += 1) {
         if (arguments[i] === value) return true;
      }
      return false;
   }
}

然后像这样使用:

1
2
'fox'.isInList('weasel', 'fox', 'stoat') // true
'fox'.isInList('weasel', 'stoat') // false

你可以为Number.prototype做同样的事情。

索引数组

如果您使用的是现代浏览器,那么indexOf始终有效。但是,对于IE8和更早的版本,您需要一个polyfill。

如果indexOf返回-1,则该项不在列表中。不过要注意,此方法不能正确检查NaN,虽然它可以匹配显式undefined,但不能像数组[1, , 2]中那样将缺少的元素与undefined匹配。

Internet Explorer 8及更早版本中用于indexOf的polyfill,或任何其他缺少它的浏览器

您可以始终使用符合标准的自定义polyfill使其在旧浏览器中工作。

在我必须为Internet Explorer 7制定解决方案的情况下,我"推出了自己的"更简单版本的不符合标准的indexOf()功能:

1
2
3
4
5
6
7
8
9
if (!Array.prototype.indexOf) {
   Array.prototype.indexOf = function(item) {
      var i = this.length;
      while (i--) {
         if (this[i] === item) return i;
      }
      return -1;
   }
}

不过,我认为从长远来看,修改Array.prototype并不是最好的解决办法。在javascript中修改ObjectArray原型会导致严重的错误。你需要决定在你自己的环境中这样做是否安全。主要注意的是,使用for ... in迭代数组(array.prototype添加了属性)将返回新的函数名作为键之一:

1
2
3
4
5
6
7
8
Array.prototype.blah = function() { console.log('blah'); };
let arr = [1, 2, 3];
for (let x in arr) { console.log(x); }
// Result:
0
1
2
blah // Extra member iterated over!

您的代码现在可以工作了,但是当将来有人添加第三方JavaScript库或插件时,这些库或插件并没有积极地保护继承的密钥,一切都可能会中断。

避免这种破坏的老方法是,在枚举期间检查每个值,以查看对象是否实际将其作为if (arr.hasOwnProperty(x))的非继承属性,然后才使用该x

避免这个额外关键问题的新ES6方法是使用of,而不是infor (let x of arr)。但是,除非您能够保证您的所有代码和第三方库都严格遵守此方法,否则为了解决此问题,您可能只希望使用上述includes


大多数答案都建议使用Array.prototype.indexOf方法,唯一的问题是它在IE9之前的任何IE版本上都不起作用。

作为替代方案,我为您提供了两个在所有浏览器上都可用的选项:

1
2
3
4
5
6
7
8
if (/Foo|Bar|Baz/.test(str)) {
  // ...
}


if (str.match("Foo|Bar|Baz")) {
  // ...
}


数组有一个indexOf方法,可用于搜索字符串:

1
2
3
4
5
6
js> a = ['foo', 'bar', 'baz']
foo,bar,baz
js> a.indexOf('bar')
1
js> a.indexOf('quux')
-1


我使用的一个技巧是

1
2
3
4
>>> ("something" in {"a string":"","somthing":"","another string":""})
false
>>> ("something" in {"a string":"","something":"","another string":""})
true

你可以做点什么

1
2
3
4
5
>>> a = ["a string","something","another string"];
>>> b = {};
>>> for(var i=0; i<a.length;i++){b[a[i]]="";} /* Transform the array in a dict */
>>> ("something" in b)
true


这是我的:

1
2
3
4
5
6
7
8
9
String.prototype.inList=function(list){
    return (Array.apply(null, arguments).indexOf(this.toString()) != -1)
}

var x = 'abc';
if (x.inList('aaa','bbb','abc'))
    console.log('yes');
else
    console.log('no');

如果你能通过一个数组,这个更快:

1
2
3
4
5
6
7
String.prototype.inList=function(list){
    return (list.indexOf(this.toString()) != -1)
}

var x = 'abc';
if (x.inList(['aaa','bbb','abc']))
    console.log('yes')

这是jspef:http://jspef.com/bmcgin-inlsit


RegExp是通用的,但我知道您使用的是数组。所以,看看这个方法。我用过它,它非常有效,而且燃烧得很快!

1
2
3
4
5
var str = 'some string with a';
var list = ['a', 'b', 'c'];
var rx = new RegExp(list.join('|'));

rx.test(str);

您还可以应用一些修改,例如:

一班轮

1
new RegExp(list.join('|')).test(str);

不区分大小写

1
var rx = new RegExp(list.join('|').concat('/i'));

< BR>

还有很多其他人!


似乎需要在数组函数中使用。

jquery->inarray

原型->array.indexof

或者,如果不使用jquery或原型,请参见以下示例:

  • http://phpjs.org/functions/in_array:432
  • http://www.bitprepository.com/equivalent-of-phps-in ou array-function.html
  • http://codingforums.com/showthread.php?t=63796

文体注释:变量命名为Thisthing that thing,应该命名为告诉你它们包含什么(名词)。


除了indexOf(其他海报都建议),使用Prototype的Enumerable.include()可以使这更简洁:

1
2
3
4
var list = ['a', 'b', 'c'];
if (list.include(str)) {
  // do stuff
}


感谢您的问题以及使用array.indexof方法的解决方案。

我使用这个解决方案中的代码创建了一个inlist()函数,imo可以使编写更简单,阅读更清晰:

1
2
3
4
5
6
7
8
9
10
function inList(psString, psList)
{
    var laList = psList.split(',');

    var i = laList.length;
    while (i--) {
        if (laList[i] === psString) return true;
    }
    return false;
}

用途:

1
2
3
if (inList('Houston', 'LA,New York,Houston') {
  // THEN do something when your string is in the list
}


使用indexof(它不适用于IE8)。

1
2
3
if (['apple', 'cherry', 'orange', 'banana'].indexOf(value) >= 0) {
    // found
}

为了支持IE8,您可以实现Mozilla的indexof。

1
2
3
if (!Array.prototype.indexOf) {
    // indexOf polyfill code here
}

通过string.prototype.match(docs)的正则表达式。

1
2
3
if (fruit.match(/^(banana|lemon|mango|pineapple)$/)) {

}


1
2
3
4
5
6
7
8
9
10
                var urllist = [];
                var p = null;
                for (var i = 0; i < spans.length - 1; i++) {
                    p = $(spans[i]).find('input').val();
                    if (urllist.indexOf(p) >= 0) {
                        growl.warning("input fields contains Duplicate Entries");
                        return;
                    }
                    urllist.push(p)
                };


我的解决方案产生如下语法:

1
2
3
4
5
// Checking to see if var 'column' is in array ['a', 'b', 'c']

if (column.isAmong(['a', 'b', 'c']) {
  // Do something
}

我通过扩展基本对象原型来实现这一点,如下所示:

1
2
3
4
5
6
7
8
Object.prototype.isAmong = function (MyArray){
   for (var a=0; a<MyArray.length; a++) {
      if (this === MyArray[a]) {
          return true;
      }
   }
   return false;
}

我们也可以将方法命名为isinarray(但可能不是inarray),或者简单地命名为isin。

优点:简单、直观、自我记录。


我很惊讶没有人提到一个简单的函数,它接受一个字符串和一个列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function in_list(needle, hay)
{
    var i, len;

    for (i = 0, len = hay.length; i < len; i++)
    {
        if (hay[i] == needle) { return true; }
    }

    return false;
}

var alist = ["test"];

console.log(in_list("test", alist));


简化版的Slaks答案也适用:

1
2
3
if ('abcdefghij'.indexOf(str) >= 0) {
    // Do something
}

….因为字符串本身就是数组。:)

如果需要,请按照前面的说明为Internet Explorer实现indexof函数。