알파벳, 숫자, 특수 문자가 섞여 있는 문자열 S가 주어졌다고 가정해 보겠습니다. 이 문제의 목표는 문자열 S를 다음 조건을 만족하는 세 개의 문자열 S1, S2, S3로 분할하는 것입니다.
- S1: 문자열 S에 포함된 모든 알파벳을 담습니다.
- S2: 문자열 S에 포함된 모든 숫자를 담습니다.
- S3: 문자열 S에 포함된 모든 특수 문자를 담습니다.
단, 세 문자열 각각의 문자는 반드시 입력 문자열에 등장한 순서 그대로 유지되어야 합니다.
예제 코드
다음은 reduce() 메서드를 활용해 문자열을 한 번의 순회만으로 분류하는 JavaScript 코드입니다.
const str = "Th!s String C0nt@1ns d1fferent ch@ract5rs";
const seperateCharacters = str => {
const strArr = str.split("");
return strArr.reduce((acc, val) => {
let { numbers, alpha, special } = acc;
if (+val) {
numbers += val;
} else if (val.toUpperCase() !== val.toLowerCase()) {
alpha += val;
} else {
special += val;
}
return { numbers, alpha, special };
}, {
numbers: '',
alpha: '',
special: ''
});
};
console.log(seperateCharacters(str));
실행 결과
콘솔에는 아래와 같은 객체가 출력됩니다.
{
numbers: '115',
alpha: 'ThsStringCntnsdfferentchractrs',
special: '! 0@ @'
}코드 동작 원리
- split(""): 문자열을 한 글자씩 잘라 배열로 만듭니다.
- reduce(): 초기값으로 빈
numbers,alpha,special속성을 가진 객체를 설정하고, 각 문자를 순회하며 해당하는 속성에 하나씩 누적합니다. - +val: 문자를 숫자로 변환했을 때 참(truthy)이면 숫자로 판별합니다.
- toUpperCase() !== toLowerCase(): 대소문자 변환 결과가 서로 다르면 알파벳으로 판별합니다. 특수 문자나 공백은 변환 후에도 값이 같으므로 마지막 분기로 넘어갑니다.
주의할 점: 숫자 "0"의 오분류
위 코드에는 한 가지 함정이 숨어 있습니다. +val은 문자 "0"을 숫자 0으로 변환하는데, 0은 자바스크립트에서 falsy(거짓 같은 값)이므로 첫 번째 조건을 통과하지 못합니다. 그 결과 위 실행 결과에서 볼 수 있듯이 "0"은 숫자 그룹이 아니라 특수 문자 그룹(special)으로 잘못 분류됩니다.
이러한 문제를 방지하려면 정규 표현식을 사용하는 것이 가장 안전합니다.
if (/[0-9]/.test(val)) {
numbers += val;
} else if (/[a-zA-Z]/.test(val)) {
alpha += val;
} else {
special += val;
}정규 표현식 기반 판별은 "0"뿐 아니라 다양한 예외 상황에서도 더 명확하고 견고하게 동작하므로, 실무에서는 이 방식을 사용하는 것을 권장합니다.