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

JavaScript 배열 중복 제거 – 하나의 인스턴스만 유지하는 방법


리터럴 값(숫자, 문자열 등)으로 이루어진 배열을 입력받아, 반복해서 등장하는 값을 모두 제거하고 각 값을 하나의 인스턴스만 남기는 JavaScript 함수를 작성해 보겠습니다. 입력 배열에는 동일한 값이 여러 번 포함되어 있을 수 있습니다.

예제 코드

아래의 deleteDuplicate 함수는 배열을 처음부터 끝까지 순회하면서, 현재 요소가 배열에서 마지막으로 등장하는 위치(lastIndexOf)와 현재 인덱스를 비교합니다. 두 위치가 서로 다르다면 같은 값이 뒤쪽에 한 번 더 존재한다는 의미이므로 해당 요소를 제거(splice)하고, 위치가 같다면 마지막 인스턴스이므로 그대로 둔 채 다음 요소로 넘어갑니다.

const arr = [1, 5, 7, 4, 1, 4, 4, 6, 4, 5, 8, 8];
const deleteDuplicate = (arr = []) => {
    for(let i = 0; i < arr.length; ){
        const el = arr[i];
        if(i !== arr.lastIndexOf(el)){
            arr.splice(i, 1);
        }
        else{
            i++;
        };
    };
};
deleteDuplicate(arr);
console.log(arr);

출력 결과

콘솔에는 다음과 같이 출력됩니다.

[ 7, 1, 6, 4, 5, 8 ]

동작 방식 설명

이 접근 방식은 각 값의 마지막 인스턴스를 유지합니다. 핵심은 splice()로 요소를 제거한 뒤 인덱스를 증가시키지 않는 것입니다. 제거된 자리에 새로운 요소가 당겨져 오기 때문에, 같은 인덱스에서 계속 검사를 반복해야 앞쪽의 중복 값들을 빠짐없이 걸러낼 수 있습니다.

더 나은 대안: Set 활용하기

만약 각 값의 첫 번째 인스턴스를 유지하고 싶다면 Set 객체를 사용하는 것이 훨씬 간단하고 효율적입니다.

const arr = [1, 5, 7, 4, 1, 4, 4, 6, 4, 5, 8, 8];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [ 1, 5, 7, 4, 6, 8 ]

Set은 중복 값을 허용하지 않는 자료구조이므로, 배열을 Set으로 변환한 뒤 스프레드 연산자로 다시 펼치기만 하면 첫 등장 순서를 유지한 채 중복이 제거됩니다.

성능 측면에서도 차이가 큽니다. lastIndexOfsplice를 조합한 방식은 매 반복마다 선형 탐색과 배열 재배치가 발생해 전체적으로 O(n²)의 시간 복잡도를 가지는 반면, Set 기반 방식은 O(n)으로 처리됩니다. 따라서 데이터 크기가 클수록 Set을 활용한 방법이 현실적으로 훨씬 유리합니다.