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

JavaScript 배열에서 고유한(유일한) 값만 추출하는 방법

실무에서 배열을 다루다 보면 다음과 같이 중복된 요소가 포함된 배열을 만나게 됩니다.

const arr = [1,1,2,2,3,4,4,5];

이번 글에서는 이런 배열을 입력받아, 원본 배열에서 단 한 번만 등장하는 요소들만 담고 있는 새로운 배열을 반환하는 JavaScript 함수를 작성해 보겠습니다. 위 예시 배열의 경우 1, 2, 4는 두 번씩 등장하므로 제외되고, 오직 3과 5만 결과에 남아야 합니다.

구현 코드

핵심 아이디어는 간단합니다. 어떤 요소가 유일한지 판별하려면 해당 요소가 처음 등장하는 위치(indexOf)마지막으로 등장하는 위치(lastIndexOf)를 비교하면 됩니다. 두 값이 같다면 그 요소는 배열 전체에서 한 번만 나타난다는 뜻입니다.

const arr = [1,1,2,2,3,4,4,5];

const extractUnique = arr => {
    const res = [];
    for(let i = 0; i < arr.length; i++){
        // 처음 등장 위치와 마지막 등장 위치가 다르면 중복 요소 → 건너뜀
        if(arr.lastIndexOf(arr[i]) !== arr.indexOf(arr[i])){
            continue;
        }
        res.push(arr[i]);
    }
    return res;
};

console.log(extractUnique(arr));

실행 결과

위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.

[ 3, 5 ]

동작 원리 살펴보기

코드의 흐름을 단계별로 정리하면 다음과 같습니다.

① 배열의 각 요소를 순회하면서 indexOf(arr[i])로 해당 값이 처음 나타나는 인덱스를 구합니다.
lastIndexOf(arr[i])로 같은 값이 마지막에 나타나는 인덱스를 구합니다.
③ 두 인덱스가 서로 다르면 같은 값이 여러 번 등장했다는 의미이므로 continue로 건너뜁니다.
④ 두 인덱스가 일치하는 경우(= 유일한 값)만 결과 배열 res에 추가합니다.

filter()를 활용한 더 간결한 방법

같은 로직을 Array.prototype.filter() 메서드를 사용하면 훨씬 선언적으로 표현할 수 있습니다.

const extractUnique = arr =>
    arr.filter(item => arr.indexOf(item) === arr.lastIndexOf(item));

console.log(extractUnique([1,1,2,2,3,4,4,5])); // [ 3, 5 ]

두 방식 모두 시간 복잡도는 O(n²)입니다. 배열 크기가 매우 크다면 Map 객체로 각 요소의 등장 횟수를 먼저 세어 O(n)으로 최적화할 수 있으니 참고하세요.