다양한 데이터 타입의 요소가 섞여 있는 배열이 주어졌을 때, 각 데이터 타입이 몇 번 등장하는지 빈도수를 Map 객체로 반환하는 JavaScript 함수를 작성해 보겠습니다.
예를 들어 다음과 같은 배열이 있다고 가정해 봅시다.
const arr = [23, 'df', undefined, null, 12, {
name: 'Rajesh'
}, [2, 4, 7], 'dfd', null, Symbol('*'), 8];이 배열에는 숫자, 문자열, undefined, null, 객체, 배열, 심볼 등 여러 타입이 혼재되어 있습니다. 우리의 목표는 이 배열을 순회하면서 각 타입의 개수를 세는 것입니다.
구현 코드
배열의 reduce() 메서드와 typeof 연산자를 활용하면 깔끔하게 해결할 수 있습니다. 초기값으로 빈 Map을 전달하고, 각 요소의 타입을 키로 사용해 개수를 누적합니다.
const arr = [23, 'df', undefined, null, 12, {
name: 'Rajesh'
}, [2, 4, 7], 'dfd', null, Symbol('*'), 8];
const countDataTypes = arr => {
return arr.reduce((acc, val) => {
const dataType = typeof val;
if(acc.has(dataType)){
acc.set(dataType, acc.get(dataType) + 1);
} else {
acc.set(dataType, 1);
}
return acc;
}, new Map());
};
console.log(countDataTypes(arr));코드 동작 원리
- reduce(): 배열을 순회하며 누적값(acc)에 결과를 쌓습니다. 초기 누적값은
new Map()입니다. - typeof val: 각 요소의 데이터 타입을 문자열로 반환합니다.
- acc.has() / acc.set() / acc.get(): 해당 타입이 이미 Map에 존재하면 기존 값에 1을 더하고, 없으면 1로 새로 등록합니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
Map(5) {
'number' => 3,
'string' => 2,
'undefined' => 1,
'object' => 4,
'symbol' => 1
}참고 사항
결과에서 'object'가 4로 집계된 점이 흥미롭습니다. 이는 일반 객체 {name: 'Rajesh'}, 배열 [2, 4, 7], 그리고 null 두 개가 모두 typeof 연산에서 'object'로 분류되기 때문입니다. JavaScript에서는 역사적인 설계상의 이유로 typeof null이 'object'를 반환하므로, null을 별도로 구분하고 싶다면 val === null 조건을 먼저 검사하는 방식으로 코드를 확장할 수 있습니다.
이처럼 reduce()와 Map을 조합하면 별도의 외부 라이브러리 없이도 데이터 타입별 빈도 분석을 손쉽게 수행할 수 있습니다.