Javascript에서 배열에 중복 값이 ​​있는지 어떻게 확인합니까?


95

중복 가능성 :
자바 스크립트 배열에서 중복 값을 찾는 가장 쉬운 방법

배열에 중복 된 값이 있는지 어떻게 확인합니까?

배열의 일부 요소가 동일하면 true를 반환합니다. 그렇지 않으면 false를 반환합니다.

['hello','goodbye','hey'] //return false because no duplicates exist
['hello','goodbye','hello'] // return true because duplicates exist

중복을 찾는 데 신경 쓰지 않고 배열에 중복이 포함되어 있는지 여부에 관계없이 부울 결과 만 원합니다.



2
중복 목록을 제거하고 싶지 않습니다. 목록에 중복 항목이 있으면 참인지 거짓인지 알고 싶습니다.
user847495

7
이 질문은 중복되지 않습니다. @ user847495는 단순히 중복이 있는지 확인하기를 원하기 때문에 모든 중복 항목을 찾는 데 필요한 것보다 솔루션이 더 빠르고 / 쉽습니다. 예를 들어 다음과 같이 할 수 있습니다. codr.io/v/bvzxhqm
alden

2
사용하여 밑줄을 , 간단한 기술var test=['hello','goodbye','hello'] ; if ( test.length != _.unique(test).length ) { // some code }
사이 램

4
표시된 질문의 중복이 아닙니다. 질문을 표시하기 전에주의하십시오.
John Weisz

답변:


224

ES2015 환경 (이 글 작성 시점 : io.js, IE11, Chrome, Firefox, WebKit nightly)이있는 경우 다음이 작동하고 빠릅니다 (즉, O (n)).

function hasDuplicates(array) {
    return (new Set(array)).size !== array.length;
}

배열에 문자열 값만 필요한 경우 다음이 작동합니다.

function hasDuplicates(array) {
    var valuesSoFar = Object.create(null);
    for (var i = 0; i < array.length; ++i) {
        var value = array[i];
        if (value in valuesSoFar) {
            return true;
        }
        valuesSoFar[value] = true;
    }
    return false;
}

우리는 valuesSoFar지금까지 배열에서 본 값이 키인 "해시 테이블"을 사용합니다 . in해당 값이 이미 발견되었는지 확인 하기 위해을 사용하여 조회합니다 . 그렇다면 우리는 루프에서 벗어나을 반환 true합니다.


문자열 값 이상으로 작동하는 함수가 필요한 경우 다음이 작동하지만 성능은 떨어집니다. O (n ) 대신 O (n 2 )입니다.

function hasDuplicates(array) {
    var valuesSoFar = [];
    for (var i = 0; i < array.length; ++i) {
        var value = array[i];
        if (valuesSoFar.indexOf(value) !== -1) {
            return true;
        }
        valuesSoFar.push(value);
    }
    return false;
}

차이점은 valuesSoFar자바 스크립트 "해시 테이블"(즉, 객체)에는 문자열 키만 있기 때문에 해시 테이블 대신 배열을 사용한다는 것 입니다. 즉,의 O (1) 조회 시간을 잃고 in대신 O (n) 조회 시간을 얻습니다 indexOf.


3
당신이 준 첫 번째 예에 대해. 유효성 검사가 정확히 반대가 아닌가? 함수 이름이 hasDuplicates이면 캐스팅 과정에서 세트의 크기가 실제로 줄어들 었는지 확인해야합니다. 따라서 불리언 연산자되어야 !==아닌===
팀 Daubenschütz

pls 편집. 6 자 이상 변경하지 않아 편집 할 수 없습니다.
Tim Daubenschütz 2015

1
MDN IE11 에 따르면 첫 번째 예제에서 사용 된 생성자를 지원하지 않습니다
adam77

1
일반 JS 버전은 true다음 배열에 대해 반환 됩니다.[1, '1']
Kunal

따라서 답변 앞에 "배열에 문자열 값만 필요한 경우".
Domenic

4

(또한 어레이 내의 객체 / 배열 요소들에 대한 또 다른 접근법 1 )이 될 수있는 2 :

function chkDuplicates(arr,justCheck){
  var len = arr.length, tmp = {}, arrtmp = arr.slice(), dupes = [];
  arrtmp.sort();
  while(len--){
   var val = arrtmp[len];
   if (/nul|nan|infini/i.test(String(val))){
     val = String(val);
    }
    if (tmp[JSON.stringify(val)]){
       if (justCheck) {return true;}
       dupes.push(val);
    }
    tmp[JSON.stringify(val)] = true;
  }
  return justCheck ? false : dupes.length ? dupes : null;
}
//usages
chkDuplicates([1,2,3,4,5],true);                           //=> false
chkDuplicates([1,2,3,4,5,9,10,5,1,2],true);                //=> true
chkDuplicates([{a:1,b:2},1,2,3,4,{a:1,b:2},[1,2,3]],true); //=> true
chkDuplicates([null,1,2,3,4,{a:1,b:2},NaN],true);          //=> false
chkDuplicates([1,2,3,4,5,1,2]);                            //=> [1,2]
chkDuplicates([1,2,3,4,5]);                                //=> null

또한보십시오...

1 에는 JSON을 지원하는 브라우저가 필요하거나그렇지 않은 경우 JSON 라이브러리 가 필요합니다.
2 편집 : 이제 함수를 사용하여 간단한 검사를하거나 중복 값의 배열을 반환 할 수 있습니다.


3
주목할 가치가있는 논스톱 퍼 문제 : 1) 정렬 할 원래 배열을 변경합니다. 2)를 구별하지 않고 null, NaN, Infinity, +Infinity, 및 -Infinity; 3) 프로토 타입이 다르더라도 동일한 고유 속성을 가진 객체는 동일한 것으로 간주됩니다.
Domenic 2011 년

1
@Domenic : 네, 언급 했어야 했어요. 원래 배열의 변형을 피하기 위해 편집되었습니다.
KooiInc 2011 년

@Domenic : null / NaN / [+/-] Infinity에 대해 수정되었습니다. 편집 내용을 참조하십시오.
KooiInc 2011 년

@Domenic : Issue 3)은 정확히 내가 원하는 것이기 때문에 실제로는 문제가되지 않습니다. 나는 프로토 타입은 신경 쓰지 않고 값만 신경 쓴다.
경외

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