web-dev-qa-db-ja.com

文字列がJavaScriptのリストにあるかどうかを確認

SQLでは、文字列が次のようにリストに含まれているかどうかを確認できます。

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

JavaScriptでこれを行うための良い方法は何ですか?これをするのはとても不器用です:

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

そして、私はこれのパフォーマンスや明確さについてはよくわかりません:

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

あるいは、スイッチ機能を使うこともできます。

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は、何らかの構文糖がなければネイティブに機能しません。

211
ErikE

EcmaScript 6

ES6を使用している場合は、項目の配列を作成して includes を使用できます。

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

これは、リスト内のindexOfの存在を適切にテストでき、[1, , 2]の真ん中の配列要素などの欠けている配列要素をNaNと一致させることができるため、undefinedよりも本質的な利点がいくつかあります。 includesUint8Arrayのような JavaScript型配列 でも動作します。

配列なし

次のようにして、新しい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;
   }
}

それを次のように使います。

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

Number.prototypeについても同じことができます。

Array.indexOf

最新のブラウザを使用している場合は、indexOfが常に機能します。ただし、IE 8以前の場合は、ポリフィルが必要です。

indexOfが-1を返した場合、その項目はリストにありません。ただし、このメソッドはNaNを正しくチェックしないため、明示的なundefinedと一致させることはできますが、配列[1, , 2]のように欠けている要素をundefinedと一致させることはできません。

Internet Explorer 8以前、またはそれを欠いている他のブラウザのindexOfの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;
   }
}

しかし、私はArray.prototypeを修正することが長期的には最良の答えだとは思いません。 JavaScriptでObjectおよびArrayプロトタイプを変更すると、深刻なバグが発生する可能性があります。自分の環境で安全であるかどうかを判断する必要があります。主な注意点は、(Array.prototypeがプロパティを追加したときに)配列をfor ... inで繰り返すと、新しい関数名がキーの1つとして返されることです。

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))およびの場合のみworkで確認することです。それでx

この余分なキーの問題を回避するための新しいES6の方法は、offor (let x of arr)の代わりにinを使用することです。しかし、あなたのすべてのコードとサードパーティのライブラリがこのメソッドに厳密に従うことを保証できないのであれば、この質問の目的のためにはおそらく上記のようにincludesを使うことになるでしょう。

136
ErikE

indexOfを呼び出すことができます。

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

回答のほとんどはArray.prototype.indexOfメソッドを示唆していますが、唯一の問題はそれがIE9より前のバージョン--- any IEで動作しないことです。

代替手段として、私はあなたにすべてのブラウザで動作するであろう2つのより多くのオプションを残す:

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


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

配列には、文字列を検索するために使用できるindexOfメソッドがあります。

js> a = ['foo', 'bar', 'baz']
foo,bar,baz
js> a.indexOf('bar')
1
js> a.indexOf('quux')
-1
25
harto

私が使ったトリックは

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

あなたは何かをすることができます

>>> 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
11
Esteban Küber

これが私のものです:

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

これは、配列を渡しても問題ない場合は速いです。

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

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

これがjsperfです。 http://jsperf.com/bmcgin-inlsit

8
Brian McGinity

RegExpは普遍的ですが、あなたが配列を使っていることを私は理解しています。だから、このアプローチをチェックしてください。私はそれを使用するために使用し、そしてそれは非常に効果的で燃え上がる速いです!

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

rx.test(str);

また、いくつかの修正を適用することもできます。

ワンライナー

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

大文字小文字を区別しません

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


そして他にもたくさん!

6
sospedra

プロトタイプの Enumerable.include() を使うとindexOf(他のポスターが推奨しています)に加えて、これをよりきれいで簡潔にすることができます。

var list = ['a', 'b', 'c'];
if (list.include(str)) {
  // do stuff
}
5
pkaeding

In_array関数を使う必要があるようです。

jQuery - > inArray

プロトタイプ - > Array.indexOf

あるいは、jQueryまたはPrototypeを使用していない場合は、これらの例を参照してください。

文体的な注意:thisthing thatthingという名前の変数には、それらに含まれるものについて何かを知らせる名前を付ける必要があります((名詞)。

5
LG_PDX

IndexOfを使用する(IE 8では機能しません)。

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

IE8をサポートするためには、MozillaのindexOfを実装することができます。

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

String.prototype.match(docs)による正規表現.

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

}
2
Tiago Medici

質問と、Array.indexOfメソッドを使用した解決策をありがとう。

私はこのソリューションのコードを使用して、IMOにより、書き込みをより単純にし、読み取りをより明確にするinList()関数を作成しました。

function inList(psString, psList) 
{
    var laList = psList.split(',');

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

使用法:

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

文字列とリストをとる単純な関数について誰も言及していなかったのは驚きです。

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

私の解決策は、このような構文になります。

// Checking to see if var 'column' is in array ['a', 'b', 'c']

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

そして私はこのように基本的なObjectプロトタイプを拡張することでこれを実装します。

Object.prototype.isAmong = function (MyArray){
   for (var a=0; a<MyArray.length; a++) {
      if (this === MyArray[a]) { 
          return true;
      }
   }
   return false;
}

代わりに、メソッドにisInArray(またはおそらくinArrayではない)または単にisInという名前を付けることができます。

利点:シンプルでわかりやすい、そして自己文書化。

0
John Hicks
                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)
                };
0
Akhil