HOWTO · JavaScript
JavaScript의 객체 배열 합계
이 튜토리얼은 JavaScript에서 객체 배열을 합하는 방법을 보여줍니다.
이 페이지의 내용
객체 배열 전체에서 특정 속성의 합계를 구하려면 각 객체를 방문하면서 해당 속성값을 누적 합계에 더하면 됩니다. 예를 들어 각 객체에 숫자인 amount가 있다면 JavaScript의 reduce()로 하나의 합계를 구할 수 있습니다. 각 반복을 명시적으로 확인하고 싶다면 forEach나 for...of 루프를 사용해도 같은 계산을 할 수 있습니다.
각 방법을 비교할 수 있도록 예제에서는 같은 레코드 세 개를 사용합니다. 이 레코드의 amount 값 합계는 600입니다.
reduce()로 객체 속성 합산하기
reduce()는 배열의 각 요소마다 콜백을 호출하고, 콜백이 반환한 값을 다음 누적값으로 전달합니다. 아래에서 콜백의 첫 번째 인수는 누적 합계이고 두 번째 인수는 현재 객체입니다. 마지막의 0은 초기 누적값입니다. 따라서 배열에 레코드가 없을 때도 계산의 시작값이 정해져 있습니다.
다음 예제를 실행해 보세요.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
const items = [
{ id: 1, amount: 100 },
{ id: 2, amount: 200 },
{ id: 3, amount: 300 },
];
const total = items.reduce((sum, item) => sum + item.amount, 0);
console.log(total);
이 코드는 대소문자를 구분하는 amount 속성을 합산하고 결과 숫자를 로그에 출력합니다. 속성 이름은 철자와 대소문자가 정확히 일치해야 합니다. item.Amount는 다른 속성을 가리킵니다. 하나의 누적 결과로 변환 과정을 명확히 표현할 수 있다면 reduce()를 사용하세요. 더할 값을 각 객체에서 계산해야 한다면 콜백 안에서 계산하면 됩니다. 별도의 map()으로 값을 추출할 수도 있지만, map()은 모든 요소를 변환할 뿐 레코드를 필터링하지는 않습니다.
forEach()로 객체 속성 합산하기
forEach는 배열의 각 항목을 방문해 콜백을 실행하지만, 누적 합계를 반환하지는 않습니다. 콜백을 호출하기 전에 별도의 변수를 초기화한 다음 각 항목의 속성값을 그 변수에 더하세요. 갱신 과정에 여러 문장이 필요할 때 이 방식이 더 읽기 쉬울 수 있습니다.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
const items = [
{ id: 1, amount: 100 },
{ id: 2, amount: 200 },
{ id: 3, amount: 300 },
];
let total = 0;
items.forEach((item) => {
total += item.amount;
});
console.log(total);
콜백에서 값을 갱신하므로 누적 변수는 let으로 선언해야 합니다. 합계의 범위를 해당 계산 안으로 제한하고, forEach의 반환값에 합계가 들어 있을 것이라고 기대하지 마세요. 명시적인 콜백과 이름이 붙은 누적 합계가 팀에서 코드를 이해하기 쉽게 해 준다면 이 방식을 선택하세요.
for...of 루프로 객체 속성 합산하기
for...of 루프도 반복 가능한 배열의 각 항목을 방문합니다. 루프 본문에서 직접 처리하므로 레코드를 건너뛰거나, 둘 이상의 속성을 살펴보거나, 계산에 다른 제어 흐름을 추가해야 할 때 유용합니다.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
const items = [
{ id: 1, amount: 100 },
{ id: 2, amount: 200 },
{ id: 3, amount: 300 },
];
let total = 0;
for (const item of items) {
total += item.amount;
}
console.log(total);
단순히 합계를 구하는 경우 세 가지 패턴은 같은 덧셈을 표현합니다. 주변 로직을 가장 이해하기 쉽게 만드는 방식을 선택하세요. 제공된 자료에는 어느 방식이 일반적으로 더 빠르다는 점을 뒷받침하는 벤치마크가 없습니다. 이 예제들은 모두 amount가 숫자라고 가정합니다. 문자열을 더하면 누적 합계와 문자열이 연결될 수 있고, undefined를 더하면 NaN이 되므로 입력 데이터를 어떻게 검증하거나 정규화할지 정해야 합니다.
누락된 값과 조건부 합계 처리하기
속성이 없거나 null일 수 있다면 해당 레코드를 합계에서 제외할지, 아니면 데이터를 거부할지 정하세요. 둘 다 0으로 처리하는 것이 의도한 정책이라면 널 병합 연산자를 사용하세요. 이 연산자는 참 같은 값인지 확인하는 대체 방식과 달리 유효한 숫자 0을 그대로 유지합니다.
이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.
const items = [
{ id: 1, amount: 100 },
{ id: 2 },
{ id: 3, amount: null },
];
const total = items.reduce((sum, item) => sum + (item.amount ?? 0), 0);
console.log(total);
널 병합 연산자는 null과 undefined를 처리하지만, 임의의 문자열을 유효한 숫자로 바꾸지는 않습니다. 외부 데이터를 다룰 때는 더하기 전에 값을 검증하세요. 예를 들어 typeof item.amount === "number"인지 확인하고, 애플리케이션의 요구에 따라 숫자가 아닌 값은 건너뛰거나 오류로 보고할 수 있습니다. 입력 형식에서 변환 규칙을 정하지 않았다면 값을 조용히 변환하지 마세요.
조건에 맞는 객체만 포함하려면 누적 콜백이나 루프 안에 조건을 넣으세요. 그러면 map()을 필터처럼 잘못 사용하는 일을 피할 수 있습니다. 다음 예제는 paid 플래그가 true인 레코드의 금액만 합산합니다.
const items = [
{ amount: 100, paid: true },
{ amount: 200, paid: false },
{ amount: 300, paid: true },
];
const paidTotal = items.reduce(
(sum, item) => sum + (item.paid ? item.amount : 0),
0
);
console.log(paidTotal);
같은 순회에서 둘 이상의 속성을 누적하려면 객체를 reduce()의 누적값으로 사용할 수 있습니다. 예를 들어 { amount: 0, tax: 0 }처럼 초기화하고 각 항목마다 갱신된 객체를 반환하면 됩니다. 속성 하나의 합계만 구할 때는 숫자 누적값이 더 간단합니다. 실제로는 누적값을 반환하는 방식, 명시적인 콜백, 직접 제어할 수 있는 루프 중 계산에 가장 잘 맞는 것을 기준으로 reduce(), forEach, for...of를 선택하세요.