문제 상황
특정한 순서 없이 문자들이 나열된 두 개의 문자열이 있다고 가정해 보겠습니다. 이때 두 문자열을 인자로 받아, 두 번째 문자열 중에서 첫 번째 문자열에 포함된 모든 문자를 제거한 결과를 반환하는 함수를 작성해야 합니다.
예를 들어 다음과 같은 문자열이 있다고 합시다.
const first = "hello world"; const second = "hey there";
위 예제에서 첫 번째 문자열 "hello world"에 포함된 문자들(h, e, l, o, 공백, w, r, d)을 두 번째 문자열 "hey there"에서 모두 걸러내면 "yt"라는 결과가 남게 됩니다.
해결 방법
가장 간단하고 직관적인 접근 방식은 split()으로 두 번째 문자열을 개별 문자 배열로 만든 뒤, filter()를 사용해 첫 번째 문자열에 포함되지 않은 문자만 남기고, 마지막에 join()으로 다시 하나의 문자열로 합치는 것입니다.
다음은 이 로직을 구현한 함수입니다.
const removeAll = (first, second) => {
const newArr = second.split("").filter(el => {
return !first.includes(el);
});
return newArr.join("");
};핵심은 includes() 메서드입니다. 각 문자가 첫 번째 문자열에 존재하는지 검사하여, 존재한다면 false를 반환해 필터링 대상에서 제외시킵니다.
전체 코드 예제
const first = "hello world";
const second = "hey there";
const removeAll = (first, second) => {
const newArr = second.split("").filter(el => {
return !first.includes(el);
});
return newArr.join("");
};
console.log(removeAll(first, second));실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
yt
"hey there"에서 "hello world"에 포함된 문자들이 모두 제거되어 'y'와 't'만 남은 것을 확인할 수 있습니다.
추가 팁: 성능 개선
문자열이 매우 긴 경우 includes()를 반복 호출하면 비효율적일 수 있습니다. 이럴 때는 첫 번째 문자열을 Set 객체로 변환하면 조회 속도를 O(1) 수준으로 개선할 수 있습니다.
const removeAllFast = (first, second) => {
const excludeSet = new Set(first);
return [...second].filter(ch => !excludeSet.has(ch)).join("");
};이 방법은 동일한 결과를 반환하면서도 대용량 문자열 처리 시 더 나은 성능을 보여줍니다.