배열에 JavaScript의 값이 포함되어 있는지 어떻게 확인합니까?


3995

JavaScript 배열에 값이 포함되어 있는지 확인하는 가장 간결하고 효율적인 방법은 무엇입니까?

이것이 내가 아는 유일한 방법입니다.

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}

이것을 달성하는 더 좋고 간결한 방법이 있습니까?

이것은 스택 오버플로 질문과 매우 밀접한 관련이 있습니다 . JavaScript 배열에서 항목을 찾는 가장 좋은 방법은 무엇입니까? 를 사용하여 배열에서 객체 찾기를 처리합니다 indexOf.


49
방금 테스트 : indexOf를 사용하는 동안 jsperf.com/find-element-in-obj-vs-array/2 (변수에 a.length를 미리 저장하는 것 제외) : .inArray) 속도가 훨씬 느림
Jörn Berkefeld

17
많은 사람들이 여기서 Array # indexOf가 최선의 선택이라고 대답했습니다. 그러나 부울로 올바르게 캐스트 할 수있는 것을 원하면 이것을 사용하십시오 : ~[1,2,3].indexOf(4)0을 반환하면 false로 평가되고 ~[1,2,3].indexOf(3)-3을 반환하면 true로 평가됩니다.
lordvlad

8
~부울로 변환하는 데 사용하려는 것이 아닙니다 !. 그러나이 경우 -1과의 동등성을 확인하려면 함수가 return [1,2,3].indexOf(3) === -1; ~이진이 아닌 종료 될 수 있으므로 값의 각 비트를 개별적으로 반전시킵니다.
mcfedr 2016 년

14
@Iordvlad [1,2,3].indexOf(4)는 실제로 -1을 반환 합니다. @mcfedr 지적으로 ~는 IS 비트 단위 NOT 연산자 , ES5 11.4.8 참조하십시오. 이진 표현은 -11로만 구성되므로 보수는입니다 0. 이는 거짓으로 평가됩니다. 다른 숫자의 보수는 0이 아니므로 참입니다. 따라서 ~잘 작동하며 종종와 함께 사용됩니다 indexOf.
mknecht

5
제목이 잘못되었습니다. 어디 [[1,2],[3,4]].includes([3,4])입니까?
mplungjan

답변:


4374

현대 브라우저가 Array#includes않는, 정확히 있고 광범위하게 지원되는 IE를 제외한 모든 사람이 :

console.log(['joe', 'jane', 'mary'].includes('jane')); //true

Array#indexOf직접적이지는 않지만 오래된 브라우저의 경우 폴리 필이 필요하지 않은을 사용할 수도 있습니다 .


많은 프레임 워크에서도 비슷한 방법을 제공합니다.

일부 프레임 워크에서는이를 함수로 구현하고 다른 프레임 워크는 함수를 배열 프로토 타입에 추가합니다.


42
MooTools에는 또한 부울을 반환하는 Array.contains가 있으며 여기에서 실제 질문처럼 들립니다.
Ryan Florence

22
또한 프로토 타입은 Array.include부울을 반환합니다
user102008

46
좋은 브라우저를 사용하는 경우 다음을 사용할 수 있습니다.array.indexOf(object) != -1
Sam Soffes

13
또한, 그나마 사용 같이 IndexOf, 조건으로 단독 첫 번째 요소는 0 반환하고 falsy로 평가되기 때문에
플러스 -

241
inArray요소의 인덱스를 반환하고 -1존재하지 않는 경우 함수의 끔찍한 이름입니다 . 부울이 반환 될 것으로 기대합니다.
Tim

434

2019 년 업데이트 :이 답변은 2008 년 (11 세)부터이며 최신 JS 사용과 관련이 없습니다. 약속 된 성능 향상은 당시의 브라우저에서 수행 된 벤치 마크를 기반으로했습니다. 최신 JS 실행 컨텍스트와 관련이 없을 수 있습니다. 쉬운 해결책이 필요하면 다른 답변을 찾으십시오. 최상의 성능이 필요한 경우 관련 실행 환경에서 벤치마킹하십시오.

다른 사람들이 말했듯이 배열을 반복하는 것이 가장 좋은 방법 일 수 있지만 JavaScript에서 루프를 줄이는 것이 가장 빠른 방법 이라는 것이 입증되었습니다while . 따라서 다음과 같이 코드를 다시 작성하십시오.

function contains(a, obj) {
    var i = a.length;
    while (i--) {
       if (a[i] === obj) {
           return true;
       }
    }
    return false;
}

물론 Array 프로토 타입을 확장 할 수도 있습니다.

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
}

이제 다음을 간단히 사용할 수 있습니다.

alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false


22
"증명 된"은 강력한 단어입니다. JS 엔진은 지속적으로 개선되고 3 년 전에 측정 된 실행 시간은 굉장히 오래되었습니다.
orip

2
@Damir-동의합니다. 가능하면 indexOf를 사용하도록 샘플을 변경하십시오.이 코드를 맹목적으로 복사하여 붙여 넣는 사람들은 최상의 성능을 얻을 수 있습니다.
orip

1
@cbmeeks 예, 관리가 반드시 필요합니다. 그것은 for (o in array)일반적으로 배열을 반복 할 때 수행해서는 안되는 경우 일 것입니다 ...
Damir Zekić

1
[1, 2, 3] .indexOf (1)> -1 경우 이렇게하는 가장 좋은 방법은 체크 인
데빈 G로드

207

indexOf 어쩌면 "ECMA-262 표준에 대한 자바 스크립트 확장입니다. 표준의 다른 구현에는 없을 수 있습니다."

예:

[1, 2, 3].indexOf(1) => 0
["foo", "bar", "baz"].indexOf("bar") => 1
[1, 2, 3].indexOf(4) => -1

AFAICS 마이크로 소프트는 않습니다 하지 대체 어떤 종류의 제공 이에,하지만 당신은 Internet Explorer의 배열 (지원을하지 않는 다른 브라우저에 유사한 기능을 추가 할 수 있습니다 indexOf당신이 원하는 경우)에, A와 빠른 Google 검색은 계시 (예를 들어, 이 일을 ).


실제로 링크 한 developer.mozilla.org 페이지에서이를 지원하지 않는 브라우저의 indexOf 확장 구현 예제가 있습니다.
Lloyd Cotten

실제로, 인덱스를 지원하지 않는 브라우저 (예 : IE7) 용 Array의 프로토 타입에 indexof를 추가하면 배열의 항목을 반복 할 때이 함수를 반복하려고 시도합니다. 추잡한.
CpILL


Object를 확인할 수 있습니까? 나는 그것이 객체의 경우에는 효과가 없다고 생각합니다
Himesh Aadeshara

169

ECMAScript 7에서 소개 Array.prototype.includes합니다.

다음과 같이 사용할 수 있습니다 :

[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false

선택적 두 번째 인수도 허용합니다 fromIndex.

[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true

달리 indexOf사용하는, 엄격한 평등 비교 , includes사용 비교 SameValueZero의 평등 알고리즘을. 즉, 배열에 다음이 포함되어 있는지 감지 할 수 있습니다 NaN.

[1, 2, NaN].includes(NaN); // true

또한 달리 indexOf, includes인덱스 누락 건너 뛰지 않습니다 :

new Array(5).includes(undefined); // true

현재 초안이지만 모든 브라우저에서 작동 하도록 폴리 필 할 수 있습니다 .


3
IE와 Microsfot 에지 (2015) (지원되지 않음 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... )
아드리아누 센드

1
또한 관련이있는 ES7 호환성 표 (크롬에서 지원하는 것처럼
보임

Object를 확인할 수 있습니까? 나는 그것이 개체의 경우에는 효과가 있다고 생각하지 않습니다
Himesh Aadeshara

128

상단 답변은 기본 유형을 가정하지만 배열에 특성 이있는 객체 가 있는지 확인하려면 Array.prototype.some () 은 매우 우아한 솔루션입니다.

const items = [ {a: '1'}, {a: '2'}, {a: '3'} ]

items.some(item => item.a === '3')  // returns true
items.some(item => item.a === '4')  // returns false

그것에 대한 좋은 점은 요소가 발견되면 반복이 중단되어 불필요한 반복 사이클이 절약된다는 것입니다.

또한 if부울을 반환하므로 명령문 에 잘 맞습니다 .

if (items.some(item => item.a === '3')) {
  // do something
}

* 의견에서 제임스가 지적한 바와 같이, 2018 년 9 월이 답변 시점에서 caniuse.com 지원 표Array.prototype.some() 가 완전히 지원됩니다.


1
오늘, 2018 년 9 월 현재, Array.prototype.some ()이 완전히 지원됩니다 : caniuse.com 지원 테이블
jamess

1
AWS Node.js Lambda의 노드> = 8.10에서 작업하므로이 방법이 좋습니다. 매우 깨끗하고 간단한 해결책! 👍🏻
Jordan

1
@jamess 잘 지원 될 수 있지만 Arrow functions이 예제에서는 지원이 잘되지 않음을 기억하십시오 . 자세한 내용은 여기를 참조하십시오 : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Kamil Witkowski

단락이 있습니까? 아니면 값을 찾더라도 전체 배열을 반복합니까?
Douglas Gaskell

@DouglasGaskell 그것은 일단 발견 된 반복을 중단합니다 (답변에 언급 됨)
Michael

112

다음과 같이 배열을 정의했다고 가정 해 봅시다.

const array = [1, 2, 3, 4]

아래에 세 가지가 있는지 확인하는 방법 3이 있습니다. 모두 true또는을 반환합니다 false.

기본 배열 방법 (ES2016부터) ( 호환성 표 )

array.includes(3) // true

사용자 정의 배열 방법으로 (ES2016 이전)

// Prefixing the method with '_' to avoid name clashes
Object.defineProperty(Array.prototype, '_includes', { value: function (v) { return this.indexOf(v) !== -1 }})
array._includes(3) // true

간단한 기능

const includes = (a, v) => a.indexOf(v) !== -1
includes(array, 3) // true

"b"가 배열 "a"에 있으면 true를 반환합니다. 다른 방법을 모르겠습니다 ...
william malo

4
이 부분은 "!! ~"를 이해하지 못합니다. IE8은 Array 객체에서 indexOf ()를 지원하지 않기 때문에 IE8에서는 작동하지 않을 것이라고 생각합니다.
svlada 2016 년

62
"~"는 숫자에서 1을 바닥, 반전 및 빼는 연산자입니다. indexOf가 실패하면 -1을 반환하므로 "~"는 -1을 "0"으로 바꿉니다. "!!"사용 boleans에 회전 수 (! 0 === 거짓)
윌리엄 말로

1
"> -1".length === "!! ~".length
super

2
부울 연산자의 비전문가 효과에 대한 지식이 부족하다고 생각합니다. 그러나 나는 읽을 수있는 코드의 가치에 동의합니다. 확실히 레이블이 지정된 함수로 이것을 감쌀 것입니다. 이것이 바로 대부분의 주요 JS 프레임 워크가하는 일입니다.
okdewit

79

여기의 자바 스크립트 1.6 호환 의 구현 Array.indexOf:

if (!Array.indexOf) {
    Array.indexOf = [].indexOf ?
        function(arr, obj, from) {
            return arr.indexOf(obj, from);
        } :
        function(arr, obj, from) { // (for IE6)
            var l = arr.length,
                i = from ? parseInt((1 * from) + (from < 0 ? l : 0), 10) : 0;
            i = i < 0 ? 0 : i;
            for (; i < l; i++) {
                if (i in arr && arr[i] === obj) {
                    return i;
                }
            }
            return -1;
        };
}

이것은 멋지지만 약간 혼란스러워 보입니다. * 1 줄과 3 줄에 대한 테스트가 아닙니까? 프로토 타입을 테스트하고 필요한 경우 Array.prototype에 함수를 추가하는 것이 더 좋지 않습니까?
Avi Flax

10
그들은 동등하지 않습니다. [].indexOf의 속기입니다 Array.prototype.indexOf. 편집증 방어적인 자바 스크립트 프로그래머는 모든 비용으로 기본 프로토 타입을 확장하지 않아도됩니다.
Már Örlygsson

1
되지 않은 [].indexOf새로운 배열을 생성하고 액세스하는 indexOf동안, Array.prototype.indexOf단지 바로 프로토 타입을 액세스?
alex

3
@alex yes [].indexOf === Array.prototype.indexOf(FireBug에서 사용해보십시오), 반대로 [].indexOf !== Array.indexOf.
Már Örlygsson

57

사용하다:

function isInArray(array, search)
{
    return array.indexOf(search) >= 0;
}

// Usage
if(isInArray(my_array, "my_value"))
{
    //...
}

25
x ? true : false일반적으로 중복됩니다. 여기 있어요
Ry-

@minitech 왜 중복이라고 말합니까?
Matías Cánepa

8
array.indexOf(search) >= 0이미 부울입니다. 그냥 return array.indexOf(search) >= 0.
Ry-

@minitech 잘 감사합니다! 실제로 나는 그러한 건축이 반환 될 수 있다는 것을 몰랐습니다. 새로운 것까지.
Matías Cánepa

말 그대로 자바 스크립트의 모든 구문을 반환 할 수 있습니다
BT

49

JavaScript Array객체를 확장 하는 것은 for-in기존 스크립트를 손상시킬 수있는 새로운 속성 (사용자 정의 메소드)을 루프에 도입하기 때문에 정말 나쁜 생각 입니다. 몇 년 전 프로토 타입 라이브러리 의 저자는 이런 종류의 것을 제거하기 위해 라이브러리 구현을 리엔지니어링해야했습니다.

페이지에서 실행되는 다른 JavaScript와의 호환성에 대해 걱정할 필요가 없다면 계속하십시오. 그렇지 않으면 더 어색하지만 더 안전한 독립형 기능 솔루션을 사용하는 것이 좋습니다.


22
동의하지 않습니다. 정확하게 For-in 루프를 배열에 사용해서는 안됩니다. 유명한 js 라이브러리 중 하나를 사용할 때 for-in 루프를 사용하면 중단됩니다
Tomas

이것이 원숭이 패치로 간주됩니까? lol 그런 사람들이 있습니다.
cbmeeks

33

짧막 한 농담:

function contains(arr, x) {
    return arr.filter(function(elem) { return elem == x }).length > 0;
}

8
array.filter(e=>e==x).length > 0에 해당 array.some(e=>e==x)하지만, some더 효율적입니다
아폴로


28

나는 다음을 사용한다 :

Array.prototype.contains = function (v) {
    return this.indexOf(v) > -1;
}

var a = [ 'foo', 'bar' ];

a.contains('foo'); // true
a.contains('fox'); // false


19

희망적으로 더 빠른 양방향 indexOf/ lastIndexOf대안

2015 년

새로운 메소드 include 는 매우 훌륭하지만, 현재는 기본적으로 지원이 없습니다.

느린 indexOf / lastIndexOf 함수를 대체하는 방법을 생각한 지 오래되었습니다.

가장 좋은 답변을 보면서 수행 가능한 방법이 이미 발견되었습니다. 그 contains중에서 @Damir Zekic이 게시 한 기능 중 가장 빠른 기능을 선택했습니다 . 그러나 벤치 마크는 2008 년부터 시작되었으며 구식이기도합니다.

나는 또한 whileover 선호 for하지만 특별한 이유는 없기 때문에 for 루프로 함수 작성을 종료했습니다. 또한로 수행 할 수 있습니다 while --.

배열을 수행하는 동안 배열의 양쪽을 확인하면 반복이 훨씬 느리면 궁금했습니다. 분명히 아니요. 따라서이 기능은 가장 많이 뽑힌 투표보다 2 배 정도 빠릅니다. 분명히 그것은 또한 네이티브보다 빠릅니다. 실제 환경에서 검색하는 값이 배열의 시작 또는 끝에 있는지 알 수없는 환경입니다.

방금 값을 가진 배열을 푸시했다는 것을 알면 lastIndexOf를 사용하는 것이 가장 좋은 해결책 일 수 있지만 큰 배열을 통과해야하고 결과가 어디에나있을 수있는 경우 상황을 더 빠르게 만드는 견고한 솔루션 일 수 있습니다.

양방향 indexOf / lastIndexOf

function bidirectionalIndexOf(a, b, c, d, e){
  for(c=a.length,d=c*1; c--; ){
    if(a[c]==b) return c; //or this[c]===b
    if(a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b
  }
  return -1
}

//Usage
bidirectionalIndexOf(array,'value');

성능 테스트

http://jsperf.com/bidirectionalindexof

테스트로 100k 항목으로 배열을 만들었습니다.

세 가지 쿼리 : 배열의 시작, 중간 및 끝.

이 내용이 흥미롭고 성능을 테스트하기를 바랍니다.

참고 : 나는 약간 수정 된 알 수 있듯이 contains(그래서 기본적으로 같이 IndexOf 및 lastIndexOf에서도 출력을 반영하기 위해 기능을 trueindexfalse함께 -1). 그것은 해를 끼치 지 않아야합니다.

배열 프로토 타입 변형

Object.defineProperty(Array.prototype,'bidirectionalIndexOf',{value:function(b,c,d,e){
  for(c=this.length,d=c*1; c--; ){
    if(this[c]==b) return c; //or this[c]===b
    if(this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b
  }
  return -1
},writable:false, enumerable:false});

// Usage
array.bidirectionalIndexOf('value');

이 함수는 true 또는 false 또는 객체, 문자열 또는 그 밖의 것을 반환하도록 쉽게 수정할 수 있습니다.

그리고 여기 while변형이 있습니다 :

function bidirectionalIndexOf(a, b, c, d){
  c=a.length; d=c-1;
  while(c--){
    if(b===a[c]) return c;
    if(b===a[d-c]) return d-c;
  }
  return c
}

// Usage
bidirectionalIndexOf(array,'value');

이것이 어떻게 가능한지?

배열에서 반사 인덱스를 얻는 간단한 계산은 너무 간단하여 실제 루프 반복을 수행하는 것보다 두 배 빠릅니다.

반복 당 세 번의 검사를 수행하는 복잡한 예는 다음과 같지만 계산 시간이 길어 코드가 느려지는 경우에만 가능합니다.

http://jsperf.com/bidirectionalindexof/2


18

공연

오늘 2020.01.07 저는 Chrome v78.0.0의 MacOs HighSierra 10.13.6, Safari v13.0.4 및 Firefox v71.0.0에서 15 개의 선택된 솔루션에 대한 테스트를 수행합니다. 결론

  • 솔루션을 기반으로 JSON, Set놀랍게도 find(K, N, O)는 모든 브라우저에서 느린이다
  • es6 includes(F)는 크롬에서만 빠릅니다.
  • for(C, D) 및 indexOf(G, H) 기반 솔루션 은 크고 작은 어레이의 모든 브라우저에서 매우 빠르므로 효율적인 솔루션을위한 최상의 선택 일 수 있습니다.
  • 루프 동안 인덱스가 감소하는 솔루션, (B) CPU 캐시 작동 방식 때문에 속도가 느려질 수 있습니다 .
  • 또한 검색 된 요소가 배열 길이의 66 % 위치에있을 때 큰 배열에 대한 테스트를 실행하고 for(C, D, E) 기반 솔루션 은 비슷한 결과를 제공합니다 (~ 630 ops / sec-safari 및 firefox의 E는 10- C 및 D보다 20 % 느림)

결과

여기에 이미지 설명을 입력하십시오

세부

10 가지 요소가있는 배열과 1 개의 요소가있는 배열의 경우 2 가지 테스트 사례를 수행합니다. 두 경우 모두 검색된 요소를 배열 중간에 넣습니다.

작은 배열-10 개 요소

당신은 당신의 컴퓨터에서 테스트를 수행 할 수 HERE

여기에 이미지 설명을 입력하십시오

큰 배열-1.000.000 요소

당신은 당신의 컴퓨터에서 테스트를 수행 할 수 HERE

여기에 이미지 설명을 입력하십시오


16

JavaScript 1.6 이상 (Firefox 1.5 이상)을 사용하는 경우 Array.indexOf 를 사용할 수 있습니다 . 그렇지 않으면 원래 코드와 비슷한 것으로 끝날 것이라고 생각합니다.


16
function inArray(elem,array)
{
    var len = array.length;
    for(var i = 0 ; i < len;i++)
    {
        if(array[i] == elem){return i;}
    }
    return -1;
} 

배열 인덱스가있는 경우, 또는 -1이없는 경우 -1을 반환합니다


16

이 스 니펫을 사용합니다 (객체, 배열, 문자열과 함께 작동).

/*
 * @function
 * @name Object.prototype.inArray
 * @description Extend Object prototype within inArray function
 *
 * @param {mix}    needle       - Search-able needle
 * @param {bool}   searchInKey  - Search needle in keys?
 *
 */
Object.defineProperty(Object.prototype, 'inArray',{
    value: function(needle, searchInKey){

        var object = this;

        if( Object.prototype.toString.call(needle) === '[object Object]' || 
            Object.prototype.toString.call(needle) === '[object Array]'){
            needle = JSON.stringify(needle);
        }

        return Object.keys(object).some(function(key){

            var value = object[key];

            if( Object.prototype.toString.call(value) === '[object Object]' || 
                Object.prototype.toString.call(value) === '[object Array]'){
                value = JSON.stringify(value);
            }

            if(searchInKey){
                if(value === needle || key === needle){
                return true;
                }
            }else{
                if(value === needle){
                    return true;
                }
            }
        });
    },
    writable: true,
    configurable: true,
    enumerable: false
});

용법:

var a = {one: "first", two: "second", foo: {three: "third"}};
a.inArray("first");          //true
a.inArray("foo");            //false
a.inArray("foo", true);      //true - search by keys
a.inArray({three: "third"}); //true

var b = ["one", "two", "three", "four", {foo: 'val'}];
b.inArray("one");         //true
b.inArray('foo');         //false
b.inArray({foo: 'val'})   //true
b.inArray("{foo: 'val'}") //false

var c = "String";
c.inArray("S");        //true
c.inArray("s");        //false
c.inArray("2", true);  //true
c.inArray("20", true); //false

15

배열에 객체가 있는지 반복적으로 확인하는 경우 조사해야 할 수도 있습니다.

  1. 삽입 정렬 을 수행하여 배열을 항상 정렬 유지 (새 개체를 올바른 위치에 배치)
  2. 개체를 제거 + 정렬 된 삽입 작업으로 업데이트하고
  3. 에서 이진 검색 조회를 사용하십시오 contains(a, obj).

2
또는 가능하면 MattMcKnight 및 ninjagecko가 제안한 것처럼 Array 사용을 완전히 중지하고 Object를 사전으로 사용하십시오.
joeytwiddle

13

모든 최신 브라우저에서 작동하는 솔루션 :

function contains(arr, obj) {
  const stringifiedObj = JSON.stringify(obj); // Cache our object to not call `JSON.stringify` on every iteration
  return arr.some(item => JSON.stringify(item) === stringifiedObj);
}

용법:

contains([{a: 1}, {a: 2}], {a: 1}); // true

IE6 + 솔루션 :

function contains(arr, obj) {
  var stringifiedObj = JSON.stringify(obj)
  return arr.some(function (item) {
    return JSON.stringify(item) === stringifiedObj;
  });
}

// .some polyfill, not needed for IE9+
if (!('some' in Array.prototype)) {
  Array.prototype.some = function (tester, that /*opt*/) {
    for (var i = 0, n = this.length; i < n; i++) {
      if (i in this && tester.call(that, this[i], i, this)) return true;
    } return false;
  };
}

용법:

contains([{a: 1}, {a: 2}], {a: 1}); // true

왜 사용 JSON.stringify합니까?

Array.indexOfArray.includes(뿐만 아니라 답변 여기에 대부분의 등)만을 기준으로 비교하지 값을 기준으로.

[{a: 1}, {a: 2}].includes({a: 1});
// false, because {a: 1} is a new object

보너스

최적화되지 않은 ES6 원 라이너 :

[{a: 1}, {a: 2}].some(item => JSON.stringify(item) === JSON.stringify({a: 1));
// true

참고 : 키의 순서가 동일한 경우 값을 기준으로 개체를 비교하는 것이 더 좋으므로 다음과 같은 패키지를 사용하여 키를 먼저 정렬 할 수 있습니다. https://www.npmjs.com/package/sort-keys


contains성능 최적화로 기능을 업데이트했습니다 . 덕분에 itinance 을 지적.


이 특정 코드 덩어리는 IE6에서 작동 할 수 있지만 (테스트되지 않음) IE는 IE9까지 ES5를 지원하지 않았습니다.
Mark Reed

성능상의 이유로 엄격하지 않아야합니다. 적어도 루프마다 "obj"를 JSON.stringify하지 않아야한다. 비용이 많이 들고 애플리케이션 속도가 느리기 때문이다. 당신은 전에 캡처해야 그 때문에 임시 변수에-루프
itinance

1
@itinance 좋은 지적. includes귀하의 제안으로 기능을 업데이트했습니다 . 내 기능으로 jsperf를 실행했습니다. lodash에 포함 된 것보다 약 5 배 느립니다. lodash는 값을 기준으로 비교하지 않으며 {a: 1}에서 찾을 수 없습니다 [{a: 1}]. 라이브러리가 있는지 모르겠습니다. 그러나 더 수행적이고 미친 듯이 복잡한 방법이 없는지 궁금합니다.
Igor Barbashin

늦은 참고 : contains([{ a: 1, b: 2 }], { b: 2, a: 1 })문자열로 된 객체가 속성의 순서를 유지하기 때문에 이것은 작동하지 않습니다 .
Heretic Monkey

1
@HereticMonkey, 사실입니다. 그래서 sort-keys하단에 메모를 추가 한 것입니다.
Igor Barbashin

12

lodash의 일부를 사용하십시오 기능을 .

간결하고 정확하며 뛰어난 크로스 플랫폼 지원을 제공합니다.

허용 된 답변은 요구 사항을 충족하지도 않습니다.

요구 사항 : JavaScript 배열에 객체가 포함되어 있는지 확인하는 가장 간결하고 효율적인 방법을 권장합니다.

허용 된 답변 :

$.inArray({'b': 2}, [{'a': 1}, {'b': 2}])
> -1

내 추천 :

_.some([{'a': 1}, {'b': 2}], {'b': 2})
> true

노트:

$ .inArray는 스칼라 배열에 스칼라 값이 있는지 여부를 결정하는 데 효과적 입니다 ...

$.inArray(2, [1,2])
> 1

...하지만 질문은 분명히 물체의 여부를 결정하는 효율적인 방법을 요구 합니다 가 배열에 포함되어 .

스칼라와 객체를 모두 처리하기 위해 다음을 수행 할 수 있습니다.

(_.isObject(item)) ? _.some(ary, item) : (_.indexOf(ary, item) > -1)

10

ECMAScript 6에는 찾기에 대한 훌륭한 제안이 있습니다.

find 메소드는 콜백이 참 값을 리턴하는 요소를 찾을 때까지 배열에있는 각 요소에 대해 콜백 함수를 한 번 실행합니다. 이러한 요소를 찾으면 find는 해당 요소의 값을 즉시 리턴합니다. 그렇지 않으면 find는 정의되지 않은 리턴을 리턴합니다. 콜백은 값이 할당 된 배열의 인덱스에 대해서만 호출됩니다. 삭제되었거나 값이 할당되지 않은 인덱스에 대해서는 호출되지 않습니다.

여기에 MDN 문서 가 있습니다.

찾기 기능은 다음과 같이 작동합니다.

function isPrime(element, index, array) {
    var start = 2;
    while (start <= Math.sqrt(element)) {
        if (element % start++ < 1) return false;
    }
    return (element > 1);
}

console.log( [4, 6, 8, 12].find(isPrime) ); // Undefined, not found
console.log( [4, 5, 8, 12].find(isPrime) ); // 5

함수정의하여 ECMAScript 5 이하에서이를 사용할 수 있습니다 .

if (!Array.prototype.find) {
  Object.defineProperty(Array.prototype, 'find', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(predicate) {
      if (this == null) {
        throw new TypeError('Array.prototype.find called on null or undefined');
      }
      if (typeof predicate !== 'function') {
        throw new TypeError('predicate must be a function');
      }
      var list = Object(this);
      var length = list.length >>> 0;
      var thisArg = arguments[1];
      var value;

      for (var i = 0; i < length; i++) {
        if (i in list) {
          value = list[i];
          if (predicate.call(thisArg, value, i, list)) {
            return value;
          }
        }
      }
      return undefined;
    }
  });
}


9

array.indexOf(x)!=-1이 작업을 수행하는 가장 간결한 방법 이지만 (Internet Explorer 이외의 브라우저에서 10 년 이상 지원하고 있지만) O (1)이 아니라 O (N)입니다. 배열이 변경되지 않으면 배열을 해시 테이블로 변환 한 다음 table[x]!==undefined또는 ===undefined:

Array.prototype.toTable = function() {
    var t = {};
    this.forEach(function(x){t[x]=true});
    return t;
}

데모:

var toRemove = [2,4].toTable();
[1,2,3,4,5].filter(function(x){return toRemove[x]===undefined})

(안타깝게도 Array.prototype.contains를 만들어 배열을 "고정"하고 해시 테이블을 this._cache에 두 줄로 저장할 수 있지만 나중에 배열을 편집하도록 선택하면 잘못된 결과가 나타납니다. 예를 들어 파이썬과 달리이 상태를 유지하십시오.)


9

"has ()"메소드가있는 Set 을 사용할 수 있습니다 .

function contains(arr, obj) {
      var proxy = new Set(arr);
      if (proxy.has(obj))
        return true;
      else
        return false;
    }

    var arr = ['Happy', 'New', 'Year'];
    console.log(contains(arr, 'Happy'));


5
나는 return proxy.has(obj)if-else 문장으로 두 줄보다 훨씬 더 깨끗 하다고 생각 합니다.
Maciej Bukowski

function contains(arr, obj) { return new Set(arr).has(obj); }
고든 빈

8

사용하다:

var myArray = ['yellow', 'orange', 'red'] ;

alert(!!~myArray.indexOf('red')); //true

데모

tilde ~이 시점에서 정확히 무엇을하는지 알기 위해서는 이 질문을 참조하십시오 . .


5
이것은 이미 1 년 반 전에 게시되었지만 반복 할 필요는 없습니다.
Shadow Wizard is Ear For You

3
실제로 게시되지 않았습니다. 답변이 아니라 답변에 대한 주석으로, 심지어 명확하고 간결하지 않습니다. 게시 해 주셔서 감사합니다. Mina Gabriel.
T.CK

6

좋아, 당신은 결과를 얻기 위해 코드를 최적화 할 수 있습니다!

더 깨끗하고 더 나은 방법은 여러 가지가 있지만 패턴을 가져 와서 적용하고 싶었습니다. JSON.stringify단순히 다음과 같이하십시오.

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (JSON.stringify(a[i]) === JSON.stringify(obj)) {
            return true;
        }
    }
    return false;
}

늦은 참고 : contains([{ a: 1, b: 2 }], { b: 2, a: 1 })문자열로 된 객체가 속성의 순서를 유지하기 때문에 이것은 작동하지 않습니다 .
Heretic Monkey

5

결코 최고는 아니지만, 나는 단지 창의력을 발휘하고 레퍼토리에 추가하고있었습니다.

이것을 사용하지 마십시오

Object.defineProperty(Array.prototype, 'exists', {
  value: function(element, index) {

    var index = index || 0

    return index === this.length ? -1 : this[index] === element ? index : this.exists(element, ++index)
  }
})


// Outputs 1
console.log(['one', 'two'].exists('two'));

// Outputs -1
console.log(['one', 'two'].exists('three'));

console.log(['one', 'two', 'three', 'four'].exists('four'));


그렇지 않으면 무엇을 사용해야합니까?
bryc

@bryc는 아마도 받아 들여진 해결책이거나 다른 해결책 일 것입니다. 성능에 신경 쓰지 않는다면 이것을 사용할 수있는 것보다
sqram

5

이 질문에 여전히 최신 구문이 추가되지 않아서 2 센트를 추가 한 것에 놀랐습니다.

객체 arrObj의 배열이 있고 그 안에서 obj를 찾고 싶다고 가정 해 봅시다.

Array.prototype. indexOf- > ( index 또는 -1 반환 )는 일반적으로 배열에서 요소의 색인을 찾는 데 사용됩니다. 객체 검색에도 사용할 수 있지만 동일한 객체에 대한 참조를 전달하는 경우에만 작동합니다.

let obj = { name: 'Sumer', age: 36 };
let arrObj = [obj, { name: 'Kishor', age: 46 }, { name: 'Rupen', age: 26 }];


console.log(arrObj.indexOf(obj));// 0
console.log(arrObj.indexOf({ name: 'Sumer', age: 36 })); //-1

console.log([1, 3, 5, 2].indexOf(2)); //3

Array.prototype. 포함 -> ( true 또는 false 반환 )

console.log(arrObj.includes(obj));  //true
console.log(arrObj.includes({ name: 'Sumer', age: 36 })); //false

console.log([1, 3, 5, 2].includes(2)); //true

Array.prototype. find- > (콜백을 수행 하고 CB에서 true를 리턴하는 첫 번째 값 / 객체 를 리턴 함)

console.log(arrObj.find(e => e.age > 40));  //{ name: 'Kishor', age: 46 }
console.log(arrObj.find(e => e.age > 40)); //{ name: 'Kishor', age: 46 }

console.log([1, 3, 5, 2].find(e => e > 2)); //3

Array.prototype. findIndex- > (콜백을 수행 하고 CB에서 true를 리턴하는 첫 번째 값 / 객체의 색인 을 리턴 함)

console.log(arrObj.findIndex(e => e.age > 40));  //1
console.log(arrObj.findIndex(e => e.age > 40)); //1

console.log([1, 3, 5, 2].findIndex(e => e > 2)); //1

find와 findIndex는 콜백을 취하기 때문에 참 조건을 창의적으로 설정하여 배열에서 객체를 가져올 수 있습니다 (참조가없는 경우에도).


5

이 요구 사항에 대한 간단한 솔루션은 find()

아래와 같은 객체 배열이 있다면

var users = [{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "admin"},
{id: "105", name: "user"}];

그런 다음 값이있는 객체가 이미 있는지 여부를 확인할 수 있습니다

let data = users.find(object => object['id'] === '104');

data가 null이면 admin이 없으면 아래처럼 기존 객체를 반환합니다.

{id: "104", name: "admin"}

그런 다음 배열에서 해당 객체의 색인을 찾아 아래 코드를 사용하여 객체를 교체 할 수 있습니다.

let indexToUpdate = users.indexOf(data);
let newObject = {id: "104", name: "customer"};
users[indexToUpdate] = newObject;//your new object
console.log(users);

당신은 아래와 같은 가치를 얻을 것입니다

[{id: "101", name: "Choose one..."},
{id: "102", name: "shilpa"},
{id: "103", name: "anita"},
{id: "104", name: "customer"},
{id: "105", name: "user"}];

이것이 누군가를 도울 수 있기를 바랍니다.


5

    function countArray(originalArray) {
     
    	var compressed = [];
    	// make a copy of the input array
    	var copyArray = originalArray.slice(0);
     
    	// first loop goes over every element
    	for (var i = 0; i < originalArray.length; i++) {
     
    		var count = 0;	
    		// loop over every element in the copy and see if it's the same
    		for (var w = 0; w < copyArray.length; w++) {
    			if (originalArray[i] == copyArray[w]) {
    				// increase amount of times duplicate is found
    				count++;
    				// sets item to undefined
    				delete copyArray[w];
    			}
    		}
     
    		if (count > 0) {
    			var a = new Object();
    			a.value = originalArray[i];
    			a.count = count;
    			compressed.push(a);
    		}
    	}
     
    	return compressed;
    };
    
    // It should go something like this:
    
    var testArray = new Array("dog", "dog", "cat", "buffalo", "wolf", "cat", "tiger", "cat");
    var newArray = countArray(testArray);
    console.log(newArray);

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.