이번 글에서는 문자열 배열을 입력받아, 같은 문자로 끝나는 두 문자열 중 하나를 삭제하고 각 끝자리 문자별로 하나의 문자열만 남기는 JavaScript 함수를 작성해 보겠습니다.
문제 이해하기
예를 들어 다음과 같은 배열이 있다고 가정해 봅시다.
const arr = ['Radar', 'Cat', 'Dog', 'Car', 'Hat'];
여기서 'Cat'과 'Hat'은 모두 't'로 끝나고, 'Dog'과 'Car'은 모두 'g'와 'r'로 각각 끝납니다. 즉, 끝자리 문자가 중복되는 경우 첫 번째로 등장한 문자열만 남기고 나머지는 배열에서 제거해야 합니다.
해결 방법
이 문제는 Map 객체를 활용하면 효율적으로 해결할 수 있습니다. 이미 등장한 끝자리 문자를 Map에 기록해 두고, 순회 중에 해당 문자가 다시 나타나면 그 요소를 배열에서 삭제하는 방식입니다.
코드 구현
const arr = ['Radar', 'Cat', 'Dog', 'Car', 'Hat'];
const deleteSameLetterWord = arr => {
const map = new Map();
for(let i = 0; i < arr.length; ){
const el = arr[i];
const last = el[el.length - 1]; // 마지막 문자 추출
if(map.has(last)){
arr.splice(i, 1); // 이미 존재하는 끝자리 문자면 요소 삭제
}else{
i++;
map.set(last, true); // 새로운 끝자리 문자라면 Map에 기록
}
}
};
deleteSameLetterWord(arr);
console.log(arr);동작 원리
함수 내부 로직을 단계별로 살펴보면 다음과 같습니다.
1. 각 문자열의 마지막 문자를 el[el.length - 1]로 추출합니다.
2. 해당 문자가 Map에 이미 존재하면 splice(i, 1)로 현재 요소를 제거하고 인덱스를 증가시키지 않습니다. (배열이 줄어들었기 때문입니다.)
3. 존재하지 않는 새로운 끝자리 문자라면 인덱스를 증가시키고 Map에 문자를 등록합니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
[ 'Radar', 'Cat', 'Dog' ]
'Car'는 'r'로 끝나지만 앞서 'Radar'가 'r'로 끝나므로 삭제되었고, 'Hat'은 't'로 끝나지만 'Cat'이 먼저 등장했기 때문에 제거된 것을 확인할 수 있습니다.
마무리
이처럼 Map을 활용하면 시간 복잡도 O(n)으로 끝자리 문자 기준 중복 문자열을 손쉽게 제거할 수 있습니다. 유사한 방식으로 첫 글자, 특정 위치의 문자 등 다양한 조건의 중복 제거에도 응용할 수 있으니 참고해 보시기 바랍니다.