자바스크립트로 개발을 하다 보면 배열에 담긴 여러 객체를 특정 속성(키)을 기준으로 묶어야 하는 경우가 자주 발생합니다. 예를 들어, 아래와 같이 자동차 정보를 담고 있는 객체 배열이 있다고 가정해 보겠습니다.
const arr = [
{
'make': 'audi',
'model': 'r8',
'year': '2012'
}, {
'make': 'audi',
'model': 'rs5',
'year': '2013'
}, {
'make': 'ford',
'model': 'mustang',
'year': '2012'
}, {
'make': 'ford',
'model': 'fusion',
'year': '2015'
}, {
'make': 'kia',
'model': 'optima',
'year': '2012'
},
];요구 사항
위와 같은 객체 배열을 입력받아, 각 객체의 'make'(제조사) 속성 값을 기준으로 객체들을 하나로 묶어주는 JavaScript 함수를 작성해야 합니다. 즉, 같은 제조사의 차량 정보들이 하나의 배열로 합쳐진 새로운 객체를 반환하면 됩니다.
기대 결과
함수 실행 후 반환되는 최종 결과는 다음과 같은 형태여야 합니다.
const output = {
'audi': [
{
'model': 'r8',
'year': '2012'
}, {
'model': 'rs5',
'year': '2013'
},
],
'ford': [
{
'model': 'mustang',
'year': '2012'
}, {
'model': 'fusion',
'year': '2015'
}
],
'kia': [
{
'model': 'optima',
'year': '2012'
}
]
};구현 코드
배열 메서드인 reduce()를 활용하면 이 문제를 매우 간결하게 해결할 수 있습니다. 전체 코드는 다음과 같습니다.
const arr = [
{
'make': 'audi',
'model': 'r8',
'year': '2012'
}, {
'make': 'audi',
'model': 'rs5',
'year': '2013'
}, {
'make': 'ford',
'model': 'mustang',
'year': '2012'
}, {
'make': 'ford',
'model': 'fusion',
'year': '2015'
}, {
'make': 'kia',
'model': 'optima',
'year': '2012'
},
];
const groupByMake = (arr = []) => {
let result = [];
result = arr.reduce((r, a) => {
r[a.make] = r[a.make] || [];
r[a.make].push(a);
return r;
}, Object.create(null));
return result;
};
console.log(groupByMake(arr));코드 동작 원리
- reduce() 순회: 배열의 각 객체를 순서대로 방문하면서 누적 객체(r)를 점진적으로 완성해 나갑니다.
- 키 초기화:
r[a.make] = r[a.make] || []구문은 해당 제조사 키가 아직 존재하지 않으면 빈 배열로 초기화합니다. - 객체 추가:
push(a)를 통해 현재 객체를 해당 제조사 키의 배열에 추가합니다. - Object.create(null): 초기값으로 사용되며, 프로토타입 체인이 없는 순수한 객체를 생성해 'toString' 같은 내장 키와의 충돌 위험을 방지합니다.
콘솔 출력 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
{
audi: [
{ make: 'audi', model: 'r8', year: '2012' },
{ make: 'audi', model: 'rs5', year: '2013' }
],
ford: [
{ make: 'ford', model: 'mustang', year: '2012' },
{ make: 'ford', model: 'fusion', year: '2015' }
],
kia: [ { make: 'kia', model: 'optima', year: '2012' } ]
}이처럼 reduce()를 사용하면 별도의 외부 라이브러리 없이도 객체 배열을 원하는 키 기준으로 손쉽게 그룹화할 수 있으며, 'year'나 'model' 등 다른 속성에도 동일한 패턴을 적용할 수 있습니다.