이번 글에서는 배열을 입력받아 중복된 값을 모두 제거한 새로운 배열을 반환하는 함수를 작성해 보겠습니다.
여기서 중요한 점은 단순히 중복을 하나만 남기는 것이 아니라, 원본 배열에서 두 번 이상 등장한 값은 새 배열에 아예 포함되지 않아야 한다는 것입니다.
예를 들어 입력 배열이 다음과 같다면,
const arr = [23, 545, 43, 232, 32, 43, 23, 43];
출력 결과는 다음과 같아야 합니다.
const output = [545, 232, 32];
indexOf()와 lastIndexOf()의 차이 이해하기
Array.prototype.indexOf() → 검색하려는 값이 배열에 존재하면 첫 번째로 등장하는 위치의 인덱스를 반환하고, 존재하지 않으면 -1을 반환합니다.
Array.prototype.lastIndexOf() → 검색하려는 값이 배열에 존재하면 마지막으로 등장하는 위치의 인덱스를 반환하고, 존재하지 않으면 -1을 반환합니다.
두 메서드 모두 기본적으로 왼쪽(앞)에서 오른쪽(뒤) 방향으로 탐색을 시작합니다. 또한 두 번째 인수가 주어지지 않으면 인덱스 0부터 탐색하며, 숫자가 전달되면 해당 인덱스부터 탐색을 시작합니다.
핵심 아이디어
여기서 중요한 포인트는 다음과 같습니다. 어떤 값에 대해 indexOf()와 lastIndexOf()가 동일한 인덱스를 가리킨다면, 그 값은 배열 안에 단 한 번만 존재한다고 확신할 수 있습니다.
반대로 두 메서드가 서로 다른 인덱스를 반환한다면, 그 값은 최소 두 번 이상 등장한 것이므로 결과 배열에서 제외해야 합니다. 이 원리를 활용하면 간단하게 문제를 해결할 수 있습니다.
전체 코드 예제
const arr = [23, 545, 43, 232, 32, 43, 23, 43];
const deleteDuplicate = (arr) => {
const output = arr.filter((item, index, array) => {
return array.indexOf(item) === array.lastIndexOf(item);
});
return output;
};
console.log(deleteDuplicate(arr));실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[ 545, 232, 32 ]
참고: 중복을 하나만 남기고 싶다면?
만약 위와 달리 중복된 값 중 첫 번째 등장한 값 하나만 남기고 싶은 경우라면 Set 객체를 활용하는 것이 가장 간단합니다.
const unique = [...new Set(arr)]; console.log(unique); // [23, 545, 43, 232, 32]
즉, 목적에 따라 적절한 방법을 선택하면 됩니다. 중복 자체를 완전히 없애려면 filter()와 indexOf()/lastIndexOf() 조합을, 중복을 하나만 남기려면 Set을 사용하세요.