문제 상황
다음과 같이 두 개의 객체가 있다고 가정해 보겠습니다.
const obj1 = {
a:12, b:8, c:17
};
const obj2 = {
a:2, b:4, c:1
};여기서 필요한 것은 두 객체를 인수로 받아, 이름(키)이 같은 속성들의 값을 하나로 합산하는 JavaScript 함수입니다. 즉, 최종 결과 객체는 다음과 같은 형태가 되어야 합니다.
const output = {
a:14, b:12, c:18
};참고: 설명의 편의상 두 개의 객체만 사용했지만, 실제로는 임의의 개수의 객체를 받아 모든 속성 값을 합산할 수 있도록 함수를 작성해야 합니다.
구현 방법
이 문제는 나머지 매개변수(rest parameter)와 배열의 reduce() 메서드를 조합하면 깔끔하게 해결할 수 있습니다. 나머지 매개변수를 사용하면 함수에 전달된 모든 객체를 하나의 배열로 수집할 수 있고, reduce()로 이 배열을 순회하며 각 객체의 속성 값을 누적 합산하면 됩니다.
const obj1 = {
a:12,
b:8,
c:17
};
const obj2 = {
a:2,
b:4,
c:1
};
const sumObjectsByKey = (...objs) => {
const res = objs.reduce((a, b) => {
for (let k in b) {
if (b.hasOwnProperty(k))
a[k] = (a[k] || 0) + b[k];
}
return a;
}, {});
return res;
}
console.log(sumObjectsByKey(obj1, obj2));코드 동작 원리
(...objs): 함수에 전달된 모든 객체를 배열 형태로 수집합니다. 덕분에 객체가 몇 개가 되더라도 유연하게 처리할 수 있습니다.reduce(): 초기값으로 빈 객체{}를 설정하고, 각 객체를 순회하면서 결과 객체에 속성 값을 하나씩 누적합니다.a[k] = (a[k] || 0) + b[k]: 결과 객체에 해당 키가 아직 없으면 0부터 시작해 값을 더하고, 이미 존재하면 기존 값에 새 값을 더합니다.hasOwnProperty(): 프로토타입 체인에 있는 속성까지 포함되는 것을 막아, 객체 자신이 직접 소유한 속성만 합산 대상으로 삼습니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같이 출력됩니다.
{ a: 14, b: 12, c: 18 }