JavaScript로 문자열을 다루다 보면 각 문자가 몇 번 등장하는지 세어야 하는 경우가 자주 있습니다. 이번 글에서는 숫자로만 이루어진 문자열을 받아, 각 숫자가 등장한 횟수를 담은 객체를 반환하는 함수를 만들어 보겠습니다.
문제 정의
다음과 같이 숫자들로 구성된 문자열이 있다고 가정해 봅시다.
const str = '11222233344444445666';
이 문자열을 입력으로 받아, 각 숫자의 등장 횟수를 나타내는 객체를 반환하는 JavaScript 함수를 작성해야 합니다. 즉, 위 문자열에 대한 기대 출력은 다음과 같습니다.
const output = {
"1": 2,
"2": 4,
"3": 3,
"4": 7,
"5": 1,
"6": 3
};해결 방법: 반복문을 활용한 빈도수 계산
가장 직관적인 접근 방식은 문자열을 한 글자씩 순회하면서, 각 숫자를 키(key)로 하는 객체에 등장 횟수를 누적하는 것입니다. 핵심 아이디어는 다음과 같습니다.
- 빈 객체
map을 생성합니다. - 문자열을 순회하며 현재 문자가
map에 이미 존재하면 기존 값에 1을 더하고, 존재하지 않으면 1로 초기화합니다. (map[str[i]] || 0) + 1패턴을 사용하면 위 로직을 한 줄로 처리할 수 있습니다. 해당 키가 없으면undefined가 되고,undefined || 0은 0이 되기 때문입니다.
예제 코드
const str = '11222233344444445666';
const mapString = str => {
const map = {};
for(let i = 0; i < str.length; i++){
map[str[i]] = (map[str[i]] || 0) + 1;
}
return map;
};
console.log(mapString(str));실행 결과
콘솔에는 다음과 같은 결과가 출력됩니다.
{ '1': 2, '2': 4, '3': 3, '4': 7, '5': 1, '6': 3 }추가 팁: reduce를 활용한 대안
같은 결과를 더 함수형 스타일로 얻고 싶다면 배열의 reduce() 메서드를 활용할 수도 있습니다.
const mapStringWithReduce = str => {
return [...str].reduce((acc, ch) => {
acc[ch] = (acc[ch] || 0) + 1;
return acc;
}, {});
};
console.log(mapStringWithReduce(str));두 방법 모두 시간 복잡도는 O(n)으로 동일하며, 문자열 길이에 비례해 선형적으로 처리됩니다. 반복문 방식이 성능 면에서 약간 유리할 수 있지만, reduce 방식은 코드가 간결하고 의도가 명확하게 드러난다는 장점이 있습니다. 상황과 팀의 코딩 스타일에 맞게 선택하시면 됩니다.