이번 튜토리얼에서는 문자열을 입력받아 영어 알파벳으로 이루어진 모든 글자를 그 다음 글자로 변경하는 자바스크립트 함수를 작성해 보겠습니다.
예를 들어, 입력 문자열이 다음과 같다면 −
const str = 'how are you';
기대되는 출력 결과는 다음과 같습니다 −
const output = 'ipx bsf zpv';
동작 원리
핵심 아이디어는 간단합니다. 문자열을 한 글자씩 순회하면서 각 문자의 유니코드 코드 값을 확인하고, 알파벳이라면 코드 값에 1을 더한 새로운 문자로 교체하면 됩니다. 다만 구현 시 두 가지 예외 상황을 반드시 고려해야 합니다.
- 알파벳이 아닌 문자: 공백이나 특수문자는 원본 그대로 유지해야 합니다.
- 'z'와 'Z' 처리: 알파벳의 마지막 글자인 z는 다음 글자가 존재하지 않으므로, 다시 'a'로 순환시켜 주어야 합니다.
예제 코드
위 로직을 구현한 전체 코드는 다음과 같습니다 −
const str = 'how are you';
const isAlpha = code => (code >= 65 && code <= 90) || (code >= 97 && code <= 122);
const isLast = code => code === 90 || code === 122;
const nextLetterString = str => {
const strArr = str.split('');
return strArr.reduce((acc, val) => {
const code = val.charCodeAt(0);
if(!isAlpha(code)){
return acc + val;
};
if(isLast(code)){
return acc + String.fromCharCode(code - 25);
};
return acc + String.fromCharCode(code + 1);
}, '');
};
console.log(nextLetterString(str));코드 설명
- isAlpha: 해당 문자가 대문자(A~Z, 코드 65~90) 또는 소문자(a~z, 코드 97~122) 범위에 속하는지 검사합니다.
- isLast: 문자가 'Z'(90) 또는 'z'(122), 즉 알파벳의 마지막 글자인지 확인합니다.
- nextLetterString:
split('')으로 문자열을 개별 문자 배열로 만든 뒤,reduce를 통해 각 문자를 변환하면서 결과 문자열을 하나씩 누적 생성합니다.
대안: map과 나머지 연산 활용하기
reduce 대신 map과 나머지 연산자(%)를 조합하면 z → a 순환 처리를 더욱 간결하게 표현할 수 있습니다.
const nextLetterString = str =>
[...str]
.map(ch => {
if (!/[a-z]/i.test(ch)) return ch; // 알파벳이 아니면 그대로 반환
const base = /[A-Z]/.test(ch) ? 65 : 97; // 대소문자 기준 코드값
return String.fromCharCode(((ch.charCodeAt(0) - base + 1) % 26) + base);
})
.join('');
console.log(nextLetterString('how are you')); // ipx bsf zpv이 방식은 코드 값에 1을 더한 뒤 26으로 나눈 나머지를 활용하기 때문에, 별도의 마지막 글자 예외 처리 없이도 z가 자연스럽게 a로 순환됩니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다 −
ipx bsf zpv