문제
영어 알파벳으로 구성된 문자열을 인수로 받는 JavaScript 함수를 작성해야 합니다. 이 함수는 문자열 내 모든 알파벳을 10자리씩 앞으로 이동시켜야 하며, 만약 알파벳이 'z'를 넘어가게 되면 다시 'a'부터 순환하여 이어가야 합니다.
예를 들어 'a'는 'k'로 이동하고, 'q'처럼 'z'를 넘어서는 문자는 다시 'a'로 돌아가 계산됩니다.
예제 코드
다음은 위 문제를 해결하는 코드입니다 −
const str = 'sample string';
const moveStrBy = (num = 10) => {
return str => {
const calcStr = (ch, code) => String
.fromCharCode(code + (ch.charCodeAt(0) - code + num) % 26);
const ACode = 'A'.charCodeAt(0);
const aCode = 'a'.charCodeAt(0);
return str.replace(/[a-z]/gi, ch => (
ch.toLowerCase() == ch
? calcStr(ch, aCode)
: calcStr(ch, ACode)
));
};
};
const moveByTen = moveStrBy();
console.log(moveByTen(str));
코드 설명
이 코드의 동작 원리를 단계별로 살펴보겠습니다.
1. 커링(Currying) 구조
moveStrBy 함수는 이동할 자릿수 num을 먼저 받고, 실제 변환할 문자열을 나중에 전달받는 고차 함수 구조입니다. 덕분에 한 번 설정한 이동 거리를 여러 문자열에 재사용할 수 있습니다.
2. 순환 이동 계산
calcStr 헬퍼 함수는 각 문자를 기준 문자('A' 또는 'a')와의 상대적 위치로 변환한 뒤, num만큼 더하고 26으로 나눈 나머지를 취합니다. 이 모듈로 연산 덕분에 'z'를 넘어도 자연스럽게 'a'부터 다시 순환하게 됩니다.
3. 대소문자 구분 처리
정규 표현식 /[a-z]/gi의 i 플래그를 통해 대소문자를 모두 찾아내며, ch.toLowerCase() == ch 비교로 해당 문자가 소문자인지 대문자인지 판별한 후 각각에 맞는 기준 아스키 코드를 적용합니다. 알파벳이 아닌 공백 등의 문자는 그대로 유지됩니다.
출력 결과
ckwzvo cdbsxq
'sample string'의 각 알파벳이 10자리씩 앞으로 이동하여 'ckwzvo cdbsxq'가 출력되는 것을 확인할 수 있습니다. 예를 들어 's'는 'c'로, 'm'은 'w'로 변환됩니다.