Ch.23 JS 핵심 패턴 — 배열 메서드 마스터
reduce와 체이닝
배열을 하나의 값으로 요약하고 싶다면?
장바구니 총 금액, 카테고리별 상품 수, 중복 제거 — 이 모든 것이 reduce 하나로 됩니다.
배열 전체를 하나의 결과로 합치는 방법은?
reduce — 배열을 순회하면서 하나의 값으로 줄여가는 메서드입니다. 가장 강력하지만 읽기 어려울 수 있습니다.
핵심 내용
reduce는 누적기(acc)에 값을 하나씩 쌓아갑니다
초기값: 누적기(acc)의 시작 값 설정
순회: 배열의 각 요소를 하나씩 처리
누적: 콜백의 반환값이 다음 acc가 됨
최종값: 마지막 acc가 결과로 반환
// 기본 문법
배열.reduce((누적기, 현재요소) => 다음누적값, 초기값)
// 합계 구하기
const numbers = [10, 20, 30, 40];
const sum = numbers.reduce((acc, n) => acc + n, 0);
// 0 → 10 → 30 → 60 → 100
// 평균 구하기
const avg = numbers.reduce((acc, n) => acc + n, 0) / numbers.length;
// 100 / 4 = 25// 실전 — 장바구니 총 금액
const cart = [
{ name: "노트북", price: 1200000, qty: 1 },
{ name: "마우스", price: 45000, qty: 2 },
{ name: "키보드", price: 89000, qty: 1 },
];
const total = cart.reduce(
(acc, item) => acc + item.price * item.qty,
0
);
// 1,379,000초기값을 반드시 넣자 두 번째 인자(초기값)를 빼먹으면 빈 배열에서 에러가 납니다. 합계는 0, 배열은 [], 객체는 {}를 초기값으로 넣으세요.
reduce로 그룹핑, 카운팅, 객체 변환이 가능합니다
// 그룹핑 — 카테고리별 분류
const items = [
{ name: "사과", category: "과일" },
{ name: "당근", category: "채소" },
{ name: "바나나", category: "과일" },
{ name: "양파", category: "채소" },
];
const grouped = items.reduce((acc, item) => {
const key = item.category;
if (!acc[key]) acc[key] = [];
acc[key].push(item.name);
return acc;
}, {});
// { 과일: ["사과", "바나나"], 채소: ["당근", "양파"] }// 카운팅 — 각 항목이 몇 번 나오는지
const votes = ["찬성", "반대", "찬성", "찬성", "반대"];
const count = votes.reduce((acc, v) => {
acc[v] = (acc[v] || 0) + 1;
return acc;
}, {});
// { 찬성: 3, 반대: 2 }
// 배열 → 객체 변환 (id를 키로)
const users = [
{ id: "u1", name: "Kim" },
{ id: "u2", name: "Lee" },
];
const userMap = users.reduce((acc, u) => {
acc[u.id] = u;
return acc;
}, {});
// { u1: {id:"u1", name:"Kim"}, u2: {id:"u2", name:"Lee"} }바이브 코더 팁 reduce가 읽기 어렵다면 AI에게 "이 reduce를 설명해줘"라고 물어보세요. 이해한 뒤 직접 수정할 수 있으면 충분합니다.
filter → map → reduce 데이터 처리 파이프라인입니다
// 실전 — 할인 상품의 총 금액 계산
const products = [
{ name: "노트북", price: 1200000, onSale: true },
{ name: "키보드", price: 89000, onSale: false },
{ name: "마우스", price: 45000, onSale: true },
{ name: "모니터", price: 350000, onSale: true },
];
const saleTotal = products
.filter((p) => p.onSale) // 할인 상품만
.map((p) => p.price * 0.8) // 20% 할인 적용
.reduce((sum, price) => sum + price, 0); // 합계
// 1,276,000// 가독성 팁 — 각 단계에 줄바꿈
const result = orders
.filter((o) => o.status === "completed") // 1. 완료된 주문만
.filter((o) => o.date >= "2024-01-01") // 2. 올해 것만
.map((o) => o.total) // 3. 금액만 추출
.reduce((sum, t) => sum + t, 0); // 4. 합계
// 읽는 법: 위에서 아래로, 한 줄씩 읽으면 됩니다
// "완료된 주문 중 올해 것의 총 금액"[1, 2, 3].reduce((acc, n) => acc + n, 0)의 결과는?
reduce의 초기값(두 번째 인자)은 생략해도 항상 안전하다
filter → map → reduce 체이닝에서 각 메서드의 역할 순서는?
핵심 용어
map
변환 — 형태를 바꿀 때 (5개 → 5개)
filter
추출 — 조건에 맞는 것만 (5개 → 2개)
find
검색 — 첫 번째 매칭 하나 (5개 → 1개)
reduce
요약 — 하나의 값으로 (5개 → 1값)
정리 노트
reduce & 체이닝 핵심 정리
reduce
- reduce
- 배열을 하나의 값으로 요약하는 메서드 (합계, 최대값, 그룹핑 등)
- 누적값(acc)
- 이전 반복의 결과가 다음 반복에 전달되는 값
- 초기값
- reduce의 두 번째 인자로 반드시 전달, 빈 배열 방어
체이닝 패턴
- filter → map → reduce
- 추출 → 변환 → 요약 순서의 데이터 파이프라인
- 가독성
- 체이닝이 길어지면 중간 변수로 분리해서 의미를 명확하게
reduce는 강력하지만 복잡하니, 단순 합계/카운트 외에는 for...of를 고려하세요.
퀴즈와 인터랙션으로 더 깊이 학습하세요
play_circle인터랙티브 레슨 시작