문제 상황
다음과 같이 여러 객체가 담긴 배열이 있다고 가정해 보겠습니다.
const arr = [
{code: "AA", gender:"male", DOB:"2000-05-15"},
{code: "AA", gender:"female", DOB:"2015-05-15"},
{code:"A0", gender:"female", DOB:"2005-01-01"},
{code: "A1", gender:"male", DOB:"2015-01-15"}
];여기서 우리는 이러한 객체 배열을 입력으로 받아 처리하는 JavaScript 함수를 작성해야 합니다. 함수가 수행해야 할 작업은 다음과 같습니다.
- 배열 내에서 "code" 속성을 기준으로 중복된 객체의 개수를 세고, 각 고유 객체에 count 속성으로 할당합니다.
- "DOB"(생년월일)와 현재 날짜로 계산한 나이가 18세 미만이면 child 속성에 1, 그렇지 않으면 0을 할당합니다.
- 추가로 성별이 여성인 경우의 개수도 함께 집계합니다.
예제 코드
이 문제를 해결하는 코드는 다음과 같습니다.
const arr = [
{code: "AA", gender:"male", DOB:"2000-05-15"},
{code: "AA", gender:"female", DOB:"2015-05-15"},
{code:"A0", gender:"female", DOB:"2005-01-01"},
{code: "A1", gender:"male", DOB:"2015-01-15"}
];
const groupAndAdd = (arr = []) => {
const result = new Map();
let nowYear = new Date().getYear();
arr.forEach(el => {
let item = result.get(el.code) || {code: el.code, count: 0, female: 0, child: 0 };
item.count++;
item.female += el.gender === "female";
item.child += nowYear − new Date(Date.parse(el.DOB)).getYear() < 18;
result.set(item.code, item);
});
return result;
};
console.log(groupAndAdd(arr));코드 동작 방식
핵심 로직을 단계별로 살펴보면 다음과 같습니다.
- Map 객체 활용: code 값을 키로 사용해 그룹화 결과를 저장합니다. Map은 키-값 쌍을 효율적으로 관리할 수 있어 이런 집계 작업에 적합합니다.
- 중복 확인 및 초기화: result.get(el.code)로 기존 항목이 있는지 확인하고, 없으면 초기값 객체({code, count: 0, female: 0, child: 0})를 새로 생성합니다.
- 개수 증가: 동일한 code가 나올 때마다 count를 1씩 증가시켜 중복 횟수를 집계합니다.
- 조건부 집계: 불리언 값은 산술 연산에서 true는 1, false는 0으로 자동 변환되는 JavaScript의 특성을 활용해, 여성 개수와 미성년자 개수를 간결하게 누적합니다.
출력 결과
콘솔에 출력되는 결과는 다음과 같습니다.
Map {
'AA' => { code: 'AA', count: 2, female: 1, child: 1 },
'A0' => { code: 'A0', count: 1, female: 1, child: 1 },
'A1' => { code: 'A1', count: 1, female: 0, child: 1 }
}결과를 해석해 보면, code가 "AA"인 객체는 원래 두 개였기 때문에 count가 2이며, 그중 하나는 여성(female: 1)이고 하나는 18세 미만(child: 1)임을 확인할 수 있습니다. 이처럼 Map과 forEach를 조합하면 별도의 라이브러리 없이도 배열 데이터를 손쉽게 그룹화하고 다양한 통계를 집계할 수 있습니다.