JavaScript로 데이터를 다루다 보면 여러 개의 객체가 담긴 배열을 특정 기준으로 묶어 하나의 객체로 재구성해야 하는 경우가 자주 발생합니다. 이번 글에서는 reduce() 메서드를 활용해 중복된 키를 가진 객체들을 깔끔하게 그룹화하는 방법을 알아보겠습니다.
문제 상황
다음과 같이 이름(name), 항공편(flight), 값(value), 타입(type)을 포함하는 객체 배열이 있다고 가정해 보겠습니다.
const arr = [
{ 'name': 'JON', flight: 100, value: 12, type: 'uns' },
{ 'name': 'JON', flight: 100, value: 35, type: 'sch' },
{ 'name': 'BILL', flight: 200, value: 33, type: 'uns' },
{ 'name': 'BILL', flight: 200, value: 45, type: 'sch' }
];여기서 우리가 만들 함수는 이 배열을 입력받아 다음 작업을 수행해야 합니다.
- 각 객체에서
value와type키를 제거합니다. type의 값을 새로운 키로 사용하고, 해당 키에value의 값을 할당합니다.- 같은
name을 가진 객체들은 하나로 병합합니다.
기대 결과
위 입력값에 대한 최종 출력은 다음과 같은 형태가 되어야 합니다.
const output = [
{ name: 'JON', flight: 100, uns: 12, sch: 35 },
{ name: 'BILL', flight: 200, uns: 33, sch: 45 }
];JON의 두 레코드가 하나로 합쳐지면서, 각각의 type('uns', 'sch')이 키가 되고 대응되는 value(12, 35)가 그 값으로 들어간 것을 확인할 수 있습니다.
해결 코드
이 문제는 클로저(closure)와 함께 Array.prototype.reduce()를 사용하면 우아하게 해결할 수 있습니다. 해시 맵 역할을 하는 객체를 미리 생성해 두면, 각 요소를 순회하면서 O(1) 시간에 기존 그룹 여부를 판단할 수 있습니다.
const arr = [
{ 'name': 'JON', flight: 100, value: 12, type: 'uns' },
{ 'name': 'JON', flight: 100, value: 35, type: 'sch' },
{ 'name': 'BILL', flight: 200, value: 33, type: 'uns' },
{ 'name': 'BILL', flight: 200, value: 45, type: 'sch' }
];
const groupArray = (arr = []) => {
const res = arr.reduce(function (hash) {
return function (r, o) {
// 해당 name으로 된 그룹이 없으면 새로 생성
if (!hash[o.name]) {
hash[o.name] = { name: o.name, flight: o.flight };
r.push(hash[o.name]);
}
// type을 키로 삼아 value를 누적
hash[o.name][o.type] = (hash[o.name][o.type] || 0) + o.value;
return r;
}
}(Object.create(null)), []);
return res;
};
console.log(groupArray(arr));코드 동작 원리
- 해시 객체 생성:
Object.create(null)로 프로토타입이 없는 순수한 객체를 만들어 키 충돌 위험 없이 해시 맵처럼 사용합니다. - 그룹 존재 여부 확인: 현재 순회 중인 객체의
name이 해시에 없다면,name과flight만 담은 새 객체를 만들고 결과 배열에 추가합니다. - 값 누적:
type값을 키로 사용해value를 더합니다. 이미 키가 존재하면 기존 값에 누적되고, 없으면 0부터 시작합니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[
{ name: 'JON', flight: 100, uns: 12, sch: 35 },
{ name: 'BILL', flight: 200, uns: 33, sch: 45 }
]마무리
이처럼 reduce()와 해시 맵을 조합하면 배열 안의 객체들을 손쉽게 그룹화하고 재구성할 수 있습니다. 이 패턴은 API 응답 데이터 정규화, 통계 집계, 중복 레코드 병합 등 실무에서 매우 유용하게 활용되므로 꼭 익혀두시길 권장합니다.