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.