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

Eri*_*ikE 231 javascript string list

在SQL中,我们可以看到字符串是否在列表中,如下所示:

Column IN ('a', 'b', 'c')
Run Code Online (Sandbox Code Playgroud)

在JavaScript中执行此操作的好方法是什么?这样做非常笨重:

if (expression1 || expression2 || str === 'a' || str === 'b' || str === 'c') {
   // do something
}
Run Code Online (Sandbox Code Playgroud)

而且我不确定这个的表现或清晰度:

if (expression1 || expression2 || {a:1, b:1, c:1}[str]) {
   // do something
}
Run Code Online (Sandbox Code Playgroud)

或者可以使用切换功能:

var str = 'a',
   flag = false;

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

if (expression1 || expression2 || flag) {
   // do something
}
Run Code Online (Sandbox Code Playgroud)

但这是一个可怕的混乱.有任何想法吗?

在这种情况下,我必须使用Internet Explorer 7作为企业内部网页面.['a', 'b', 'c'].indexOf(str) !== -1如果没有一些语法糖,那么本身就不会工作.

SLa*_*aks 257

你可以打电话indexOf:

if (['a', 'b', 'c'].indexOf(str) >= 0) {
    //do something
}
Run Code Online (Sandbox Code Playgroud)

  • `Array.prototype.indexOf`的唯一问题是它不能在IE上工作,遗憾的是IE8缺少这种方法. (15认同)
  • @ImJasonH:该页面上的代码真的很糟糕恕我直言,例如,检查`Array.indexOf`是否存在,然后重写'Array.prototype.indexOf`,它们*不是*同一个东西.我建议在这里提供Mozilla的实现:https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/IndexOf (8认同)
  • 但是如果你愿意,你可以定义它.见http://soledadpenades.com/2007/05/17/arrayindexof-in-internet-explorer/ (2认同)

Eri*_*ikE 171

EcmaScript 6

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

['a', 'b', 'c'].includes('b')
Run Code Online (Sandbox Code Playgroud)

这有一些固有的优势在indexOf,因为它可以正确测试中是否存在NaN在列表中,并且可以匹配缺少的数组元素,如中间的一个中[1, , 2]undefined.includes也适用于JavaScript类型的数组,如Uint8Array.

没有数组

您可以isInList按如下方式向字符串添加新属性:

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;
   }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

'fox'.isInList('weasel', 'fox', 'stoat') // true
'fox'.isInList('weasel', 'stoat') // false
Run Code Online (Sandbox Code Playgroud)

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

Array.indexOf

如果您使用的是现代浏览器,请indexOf始终使用.但是,对于IE8及更早版本,您需要一个polyfill.

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

indexOfInternet Explorer 8及更早版本中的Polyfill ,或缺少它的任何其他浏览器

您始终可以使用符合标准的自定义polyfill,以便在旧版浏览器中使用.

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

if (!Array.prototype.indexOf) {
   Array.prototype.indexOf = function(item) {
      var i = this.length;
      while (i--) {
         if (this[i] === item) return i;
      }
      return -1;
   }
}
Run Code Online (Sandbox Code Playgroud)

但是,Array.prototype从长远来看,我不认为修改是最好的答案.在JavaScript中修改ObjectArray原型可能会导致严重的错误.您需要决定在您自己的环境中这样做是否安全.主要的注意事项是迭代一个数组(当Array.prototype添加属性时)for ... in将返回新的函数名称作为其中一个键:

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!
Run Code Online (Sandbox Code Playgroud)

您的代码现在可以正常工作,但是当某个人在将来添加第三方JavaScript库或插件时,并不热心防范继承密钥,一切都会破坏.

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

新的ES6避免这个额外关键问题的方法是使用of而不是in,for (let x of arr).但是,除非您能保证所有代码和第三方库都严格遵守此方法,否则出于本问题的目的,您可能只想使用includes上述方法.

  • 这是MDN提供的`indexOf`的另一个好的[PolyFill](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf#Polyfill).它基本上做同样的事情,但有一些短路,便于评估. (2认同)

CMS*_*CMS 52

大多数答案都提出了这个Array.prototype.indexOf方法,唯一的问题是IE9之前的任何 IE版本都无法使用.

作为替代方案,我给你留下了两个适用于所有浏览器的选项:

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


if (str.match("Foo|Bar|Baz")) {
  // ...
}
Run Code Online (Sandbox Code Playgroud)

  • 这将匹配"HiFooThere"` - 我将改为`/ ^(?:Foo | Bar | Baz)$ /`(字符串开头,非捕获组,字符串结尾). (12认同)

har*_*rto 27

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

js> a = ['foo', 'bar', 'baz']
foo,bar,baz
js> a.indexOf('bar')
1
js> a.indexOf('quux')
-1
Run Code Online (Sandbox Code Playgroud)

  • 这将在旧浏览器上失败. (3认同)
  • @epascarello:不仅在旧版浏览器中,即使在IE8中,它也会在*any*IE上失败:( (2认同)

Est*_*ber 11

我用过的一个技巧是

>>> ("something" in {"a string":"", "somthing":"", "another string":""})
false
>>> ("something" in {"a string":"", "something":"", "another string":""})
true
Run Code Online (Sandbox Code Playgroud)

你可以做点什么

>>> 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
Run Code Online (Sandbox Code Playgroud)


Bri*_*ity 8

这是我的:

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');
Run Code Online (Sandbox Code Playgroud)

如果您对传递数组没问题,那么这个更快:

String.prototype.inList=function(list){
    return (list.indexOf(this.toString()) != -1)
}

var x = 'abc';
if (x.inList(['aaa','bbb','abc']))
    console.log('yes')
Run Code Online (Sandbox Code Playgroud)

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


sos*_*dra 6

RegExp是通用的,但我知道你正在使用数组.所以,看看这种方法.我习惯使用它,它非常有效且速度极快!

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

rx.test(str);
Run Code Online (Sandbox Code Playgroud)

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

一衬垫

new RegExp(list.join('|')).test(str);
Run Code Online (Sandbox Code Playgroud)

不区分大小写

var rx = new RegExp(list.join('|').concat('/i'));
Run Code Online (Sandbox Code Playgroud)


还有很多人!


pka*_*ing 5

除了indexOf(其他海报提出的建议)之外,使用原型的Enumerable.include()可以使这更加简洁明了:

var list = ['a', 'b', 'c'];
if (list.include(str)) {
  // do stuff
}
Run Code Online (Sandbox Code Playgroud)

  • Enumerable.include()已被弃用,但[Array.prototype.includes()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)即将推出,并且已经在大多数浏览器中工作,除了IE(当然)和Edge(当然). (4认同)

小智 5

看起来你需要使用in_array函数.

jQuery - > inArray

Prototype - > Array.indexOf

或者,如果您不使用jQuery或Prototype,请参阅这些示例:

文体注释:这个名称为thisthing的变量,应该被命名为告诉你它们包含的内容(名词).


Tia*_*ici 5

使用indexOf(不适用于IE8)。

if (['apple', 'cherry', 'orange', 'banana'].indexOf(value) >= 0) {
    // found
}
Run Code Online (Sandbox Code Playgroud)

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

if (!Array.prototype.indexOf) {
    // indexOf polyfill code here
}
Run Code Online (Sandbox Code Playgroud)

通过String.prototype.match(docs)进行正则表达式。

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

}
Run Code Online (Sandbox Code Playgroud)