Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

자바스크립트(JavaScript) 배열에서 중복으로 등장한 요소 모두 제거하기

배열을 인수로 받아 중복된 값을 모두 제거한 새로운 배열을 반환하는 함수를 작성해 보겠습니다. 단순히 중복을 하나만 남기는 방식이 아니라, 원본 배열에서 두 번 이상 등장한 값은 새 배열에 아예 포함되지 않도록 처리해야 합니다.

예를 들어 입력이 다음과 같다면,

const arr = [763,55,43,22,32,43,763,43];

출력 결과는 아래와 같아야 합니다.

const output = [55, 22, 32];

이 문제는 자바스크립트의 다음 두 가지 배열 메서드를 활용해 해결할 수 있습니다.

  • Array.prototype.indexOf() — 검색 대상 요소가 배열에 존재하면 첫 번째로 등장하는 위치의 인덱스를, 존재하지 않으면 -1을 반환합니다.
  • Array.prototype.lastIndexOf() — 검색 대상 요소가 배열에 존재하면 마지막으로 등장하는 위치의 인덱스를, 존재하지 않으면 -1을 반환합니다.

동작 원리

핵심 아이디어는 간단합니다. 어떤 요소에 대해 indexOf()lastIndexOf()의 반환값이 서로 같다면, 그 요소는 배열 안에서 단 한 번만 등장한다는 뜻입니다. 반대로 요소가 여러 번 나타나면 두 메서드의 결과가 달라집니다. 따라서 filter()로 이 조건을 만족하는 요소만 걸러내면, 완전히 고유한(unique) 값들만 남은 새 배열을 얻을 수 있습니다.

예제 코드

실제 구현 코드는 다음과 같습니다.

const arr = [763,55,43,22,32,43,763,43];
const deleteDuplicate = (arr) => {
    const output = arr.filter((item, index, array) => {
        return array.indexOf(item) === array.lastIndexOf(item);
    });
    return output;
};
console.log(deleteDuplicate(arr));

실행 결과

코드를 실행하면 콘솔에 다음과 같이 출력됩니다.

[ 55, 22, 32 ]

참고: 성능 최적화 팁

위 방식은 각 요소마다 indexOf()lastIndexOf()를 호출하기 때문에 시간 복잡도가 O(n²)입니다. 배열의 크기가 매우 크다면, Map 객체로 각 값의 등장 횟수를 미리 계산해 두는 방식(O(n))이 더 효율적입니다.

const deleteDuplicate = (arr) => {
    const countMap = arr.reduce((map, item) => {
        map.set(item, (map.get(item) || 0) + 1);
        return map;
    }, new Map());
    
    return arr.filter((item) => countMap.get(item) === 1);
};

console.log(deleteDuplicate([763,55,43,22,32,43,763,43])); // [ 55, 22, 32 ]

배열 규모가 작다면 첫 번째 방법으로도 충분하지만, 대용량 데이터를 다룰 때는 후자의 접근 방식을 권장합니다.