[javascript] 자바스크립트 배열 요소의 중복 체크

기본 데이터 타입 배열의 중복 체크

셋(Set)은 중복 없는 값들을 목록으로 유지하는 객체입니다. 맵(Map)에서 키만 있다고 생각하면 됩니다.

맵은 생성자 인자로 배열을 넣을 수 있습니다.

배열에 중복이 있으면 중복 요소들은 배제하고 셋(Set) 목록을 생성합니다.

셋(Set)은 요소의 개수를 size 속성에 가지고 있고, 배열은 length 속성에 가지고 있습니다.

속성이 다르므로 주의해야 합니다.

size 보다 length는 항상 크거나 같습니다. 배열에 중복이 없으면 둘의 요소 개수는 같고, 그렇지 않으면 length가 항상 큽니다. size보다 length가 크면 중복이 있어서 배제된 배열 요소가 있다는 뜻이 됩니다.

const arrDup = ['라이언', '어피치', '프로도', '콘', '라이언', '프로도'];
const set = new Set(arrDup);

if(set.size < arrDup.length){
  console.log("중복이 있슴.");
}

객체 배열의 중복 체크

객체를 요소로 하는 배열은 앞 서처럼 셋(Set)으로 길이 비교를 할 수 없습니다.

배열의 요소인 객체 단위로는 서로 비교를 해서 객체가 같은지를 비교할 수 없기 때문입니다.

예를 들어보겠습니다.

const arrDup = [{name:'라이언',company:'kakao'}, {name:'브라운',company:'naver'}, {name:'라이언',company:'kakao'}, {name:'펭수',company:'ebs'}];
console.log(arrDup[0] === arrDup[2]); // false

const set = new Set(arrDup);
console.log(set.size); // 4

객체 배열의 첫 번째와 세 번째 객체는 키와 값이 완전히 동일합니다.

하지만 두 배열 요소를 비교하면 false가 됩니다.

객체를 비교하면 객체의 키나 값을 비교하는 것이 아니라 참조 주소를 비교하기 때문에 같아질 수가 없습니다.

그리고 앞서처럼 객체 배열을 셋(Set)으로 변경하면 셋의 요소 개수는 배열과 동일하게 4개가 됩니다.

셋을 생성할 때도 마찬가지로 객체 요소를 단순 비교하기 때문에 같은 요소가 생길 수가 없습니다.

그래서 셋을 만들 때 다음처럼 객체를 문자열로 바꿔서 비교를 하는 우회적인 방법을 사용해서 중복 체크를 합니다.

const set = new Set(arrDup.map(JSON.stringify));
console.log(set.size); // 3

간단하지만 처리 개념을 이해하는 것이 중요합니다.

셋(Set)은 배열을 인자로 받아서 중복 요소를 배제하고 셋 객체를 생성합니다.

배열의 내장 메서드인 map()을 이용해서 배열의 요소들에 처리 함수를 적용하는데 JSON.stringify 메서드를 적용합니다.

JSON 객체의 내장 메서드로 객체를 문자열 나열로 변경합니다.

예를 든 객체 배열은 최종적으로 셋(Set) 생성자 인자로 다음과 같은 문자열 배열로 적용됩니다.

['{"name":"라이언","company":"kakao"}', '{"name":"브라운","company":"naver"}', '{"name":"라이언","company":"kakao"}', '{"name":"펭수","company":"ebs"}']

따옴표로 객체를 감싸서 문자열로 변환된 배열 요소는 셋에 추가되면서 세 번째 요소는 이미 첫 번째 문자열에서 추가된 요소이기 때문에 제외가 됩니다.

최종적으로 셋의 size 속성은 3이 됩니다.

가장 중요한 핵심은 배열의 map() 메서드를 사용해 배열의 각 요소에 JSON.stringify 메서드를 적용해서 객체를 문자열로 변환하는 것입니다.

도움이 되는 다른 글

> 자바스크립트 배열의 중복을 제거하는 방법 총정리