자바 스크립트에서 문자열이 목록에 있는지 확인


262

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어떤 구문 설탕없이 기본적으로 작동하지 않습니다.


1
"string is in list"와 "array includes an object"의 차이점이 정확히 무엇인지 설명해 주시겠습니까?
Michał Perłakowski

2
@Gothdo리스트가 항상 배열이 아니고 문자열이 객체가 아니기 때문에? 어떻게 더 명확해질 수 있습니까?
ErikE

@ErikE 만약 이것이 당신 이 NOTE 에서 언급 한 것이라면이 질문은 닫혀 져야하고 더 이상의 현상금 / 응답이 허용되지 않아야합니다. 이미 게시 된 답변 만 있으면 누구나 도움을받을 수 있습니다.
Vikasdeep Singh 2018

@VicJordan 아마도 당신은 더 이상 적용되지 않으므로 코멘트를 삭제하고 싶을 것입니다.
ErikE

답변:


279

당신은 전화 할 수 있습니다 indexOf:

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

15
유일한 문제 Array.prototype.indexOf는 IE에서 작동하지 않는다는 것입니다. 슬프게도 IE8 조차도이 방법이 부족합니다.
CMS

2
그러나 원하는 경우 정의 할 수 있습니다. 참조 soledadpenades.com/2007/05/17/arrayindexof-in-internet-explorer
제이슨 홀

"실제"제품은 다음과 같습니다. developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
ErikE

8
@ImJasonH : 해당 페이지의 코드는 정말 예를 들어 정말 나쁜 IMHO, 경우는 검사입니다 Array.indexOf무시 전에 존재 Array.prototype.indexOf입니다 하지 같은 일. Mozilla에서 구현 한 developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/…를
CMS

1
@CMS, @Emtucifor, 모질라 구현이 훨씬 낫습니다.
Jason Hall

230

EcmaScript 6

ES6을 사용하는 경우 항목의 배열을 구성하고 다음을 사용할 수 있습니다 includes.

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

이 이상의 몇 가지 고유의 장점이 indexOf제대로의 존재를 테스트 할 수 있기 때문에 NaN목록을, 등의 중간 하나없는 배열 요소와 일치 수 [1, , 2]에를 undefined. 와 같은 JavaScript 형식의 배열includes 에서도 작동합니다 .Uint8Array

브라우저 지원 (IE 또는 Edge 등)에 대해 우려가있는 경우 CanIUse.Com 에서 확인할Array.includes 수 있으며 누락 된 브라우저 또는 브라우저 버전을 대상으로하려면 polyfilling 에 polyfill.io를 사용하는 includes것이 좋습니다 .

배열없이

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항상 작동합니다. 그러나 IE8 및 이전 버전의 경우 폴리 필이 필요합니다.

경우 indexOf-1을 반환 항목은 목록에 없습니다. 그러나이 메소드는 제대로 검사하지 않으며 NaN명시적인 값과 일치 undefined할 수 있지만 누락 된 요소 undefined는 배열에서 와 일치 할 수 없습니다 [1, , 2].

IE 용 폴리 필 indexOf또는 includes지원되지 않는 기타 브라우저 / 버전

위에서 언급 한 polyfill.io 와 같은 서비스를 사용하지 않으려는 경우 언제든지 자체 소스 코드 표준 호환 사용자 정의 폴리 필을 포함 할 수 있습니다. 예를 들어, Mozilla Developer Network에는에 대한 것이 indexOf있습니다.

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에서 수정 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!

코드가 지금 작동 할 수도 있지만 미래의 누군가가 상속 된 키를 열심히 보호하지 않는 타사 JavaScript 라이브러리 또는 플러그인을 추가하는 순간 모든 것이 깨질 수 있습니다.

그 파손을 방지하는 기존 방법은 객체가 실제로 상속과 재산으로 보유하고 있는지 확인하기 위해 각 값을 확인하려면 열거하는 동안이며, if (arr.hasOwnProperty(x))그리고 오직 다음 그와 함께 작업 x.

이 추가 키 문제를 피하는 새로운 ES6 방법 ofin, 대신 사용하는 것입니다 for (let x of arr). 그러나 모든 코드 및 타사 라이브러리 가이 방법을 엄격하게 준수한다고 보장 할 수 없다면이 질문의 목적을 위해 includes위에서 언급 한대로 사용하고 싶을 것입니다 .


2
MDN 에서 제공하는 또 다른 좋은 PolyFillindexOf있습니다. 기본적으로 동일한 작업을 수행하지만 쉬운 평가를 위해 두 개의 단락이 있습니다.
KyleMit

1
Downvoter : 의견을 말하십시오. 이것에 무슨 문제가 있습니까? 이 기능은 표준을 준수하지 않으며 시도하지 않습니다.
ErikE

@KyleMit 링크에서 언급 한 polyfill과 같이 이미 테스트 된 것을 사용해야합니다. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
lmiguelmh

@lmiguelmh Mozilla 문서 자체에서 직접 링크를 게시 한 "polyfill"은 어떻습니까? 어쨌든이 함수는 너무 간단하여 테스트에 대해 너무 걱정하지 않습니다. 그리고 누구든지 "이미 테스트 된"기능을 사용하지 말고 자신이 사용하는 모든 것을 테스트해야합니다. 따라서 귀하의 의견은 약간 잘못되었습니다. 내 기능에 특정 결함이 있는지 확인 했습니까?
ErikE

@ErikE 당신이 바로이 기능은 죽었고 당신의 대답을 사용하는 사람은 그것을 알아야합니다. "답변"을 찾고 있었기 때문에 처음부터 귀하의 링크를 보지 못했습니다
lmiguelmh

53

답변의 대부분은 제안 Array.prototype.indexOf방법은, 유일한 문제는 그것이 작동하지 것입니다 어떤 IE9 이전 IE 버전.

대안으로 모든 브라우저에서 작동하는 두 가지 옵션을 더 남겨 둡니다.

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


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

흠, CMS를 언급 해 주셔서 감사합니다. 이것이 바로 회사 인트라넷을위한 것이며 IE를 사용합니다. 정규 표현식 메소드는 willies를 제공하므로 루프하는 함수를 만들거나 내 게시물에서 제안한 객체 메소드를 사용해야합니다 (세 번째 코드 블록).
ErikE

13
이것은 일치합니다 "HiFooThere"- /^(?:Foo|Bar|Baz)$/대신에 시작합니다 (문자열의 시작, 캡처하지 않는 그룹, 문자열의 끝).
TrueWill

indexOfMDN 에 따라 IE 9 이상에서 지원됩니다 .
krock

28

배열에는 indexOf문자열을 검색하는 데 사용할 수 있는 방법이 있습니다.

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

3
이전 브라우저에서는 실패합니다.
epascarello 2

죄송합니다. IE에서 작동하지 않는다고 언급하면 ​​좋을 것입니다. :)
ErikE

2
@epascarello : 오래된 브라우저뿐만 아니라 IE8에서도 모든 IE에서 실패합니다. (
CMS

12

내가 사용한 트릭은

>>> ("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

보이저, 내 질문의 세 번째 코드 블록에서 알 수 있듯이 항목을 역 참조하려고 시도하는 것보다 더 빠르거나 느리거나 더 나은 방법으로 "in"을 사용하고 있습니까? 또한, 당신이 그 일을 반복하려고한다면, 그 시점에서 요소가 배열에 있는지 확인할 수도 있습니다 ... 루프를 함수로 감싸십시오. 그리고 가치있는 var i=a.length;while (i--) {/*use a[i]*/}것은 가장 빠른 루프 방법입니다 (역순이 허용되는 경우).
ErikE

@ Emtucifor : 실제로 수행중인 작업에 따라 다르며 다른 자바 스크립트 엔진에서 다르게 작동 할 수 있다고 생각합니다. 데이터가 어느 시점에서 사전을 사용해야하는 경우 이런 식으로 작성하는 것이 좋습니다. dict 객체가 생성되면 엔진에 대한 구현 세부 정보 (객체에 해시 테이블 사용) 때문에 이것이 더 빠를 것이라고 생각합니다 .
Esteban Küber

JavaScript에서는 dict라고하는 것이 아니라 object 라고 합니다 .
Solomon Ucko

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

배열을 전달해도 괜찮다면 더 빠릅니다.

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


솔직히 배열을 전달하는 것이 더 유용 할 것입니다 Array. 아마도 프로토 타입 에 있어야합니다 Array.prototype.contains.
Solomon Ucko

6

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


그리고 많은 다른 사람들!


정규식을 사용하려면 많은 특수 문자를 피해야합니다. 또한 덜 명확합니다. 나는 그것이 좋은 해결책이라고 생각하지 않습니다.
ErikE

@ErikE 귀하의 예약을 이해하므로 RegExp를 사용하지 않는 다른 코드를 추가하여 답변을 업데이트했습니다 .IE와 호환되며 매우 관용적이며 빠릅니다.
sospedra

귀하의 추가 코드는 Regex 솔루션을 게시하기로 결정하기 5 년 전에 제공 한 답변과 거의 중복됩니다. 참여해 주셔서 감사하며 동시에 귀하의 이전 답변으로 돌아가는 것이 가장 좋습니다.
ErikE

@ErikE 네, 맞습니다. 질문에 답을 확인하는 데 사용하지 않습니다. 그리고 나는 그것이 정말로 비슷하다는 것에 동의합니다.
sospedra

6

indexOf 사용 (IE8에서는 작동하지 않습니다).

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)$/)) {

}

1
페이지의 다른 답변을 정확하게 복제하고 있음을 알고 있습니까? 이것은 어떤 가치도 추가하지 않습니다.
ErikE

5

in_array 함수를 사용해야 할 것 같습니다.

jQuery-> inArray

프로토 타입-> Array.indexOf

또는 jQuery 또는 프로토 타입을 사용하지 않는 경우 다음 예제를 참조하십시오.

양식 참고 사항 : 이것으로 명명 된 변수는 이름에 포함 된 이름 (명사)에 대해 알려주도록 명명되어야합니다.


아, 그들은 변수가 아니었지만 표현식에 대한 임의의 자리 표시 자로 사용되었습니다 ... 스크립트를 어떻게 사용할 계획인지에 대한 예일뿐입니다.
ErikE

5

indexOf프로토 타입의 Enumerable.include () 를 사용하면 ( 다른 포스터에서 제안한 것 외에도 ) 더 깔끔하고 간결하게 만들 수 있습니다.

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

5
Enumerable.include ()는 더 이상 사용되지 않지만 Array.prototype.includes () 가 제공되며 IE (물론) 및 Edge (물론)를 제외한 대부분의 브라우저에서 이미 작동하고 있습니다.
whitebeard

2

질문과 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
}

1
Javascript 배열 리터럴은 매우 쉽습니다 'Houston'.inList(['LA', 'New York', 'Houston']). 할 수있을 때 왜 분할하는지 알 수 없습니다 . 아마도 if (!String.prototype.inList) {String.prototype.inList = function(arr) {return arr.indexOf(this) >= 0};}또는 당신의 while방법을 사용합니다 .
ErikE

0

문자열과 목록을 취하는 간단한 함수를 언급 한 사람이 아무도 없습니다.

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

은 당신이 제안한대로 정확히 했어요 , 샘, 8 월 27 일 11 일 1시 29 분에. 사실, 내 선택한 대답은 단지와 문자열 공급, 거의 같은 일 아니라 매개 변수보다.
ErikE

@ErikE 죄송합니다. 짐의 대답은 당신이 말한 것처럼 이상하게 보였습니다. 그리고 당신의 대답은을 반환합니다 int. 어떤 사람들은이 질문에 답하기를 원할 것입니다 bool. 그것이 몇몇 사람들에게 도움이 될 것이라고 생각했습니다.
Samuel Parkinson

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으로 지정할 수 있습니다.

장점 : 간단하고 간단하며 자체 문서화.


Object를 확장하는 데 문제가있을 수 있습니다. bolinfest.com/javascript/inheritance.php 의 "Google Maps 팀은 어려운 방법을 배웠습니다"및 브라우저 구현 또는 다른 사용자 코드와 호환되지 않습니다. 해시 맵이 생성되면 배열을 반복하는 것이 해시 맵에서 키를 찾는 것보다 느리기 때문에 ErikE의 대답이 가장 좋은 방법이라고 생각합니다. myValues[key];여기서 myValues는 객체이고 키는 문자열 또는 숫자입니다.
HMR

-1

SLaks의 답변 의 단순화 된 버전 도 작동합니다.

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

.... 문자열은 배열 자체이기 때문에. :)

필요한 경우 앞에서 설명한대로 Internet Explorer 용 indexof 함수를 구현하십시오.


1
이것은 의도하지 않은 단일 문자 문자열에서만 작동합니다.
ErikE
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.