Ch.23 JS 핵심 패턴 — 배열 메서드 마스터

reduce와 체이닝

reduce의 누적기 개념을 이해한다reduce로 합계, 그룹핑, 객체 변환을 할 수 있다filter → map → reduce 파이프라인을 읽을 수 있다

배열을 하나의 값으로 요약하고 싶다면?

장바구니 총 금액, 카테고리별 상품 수, 중복 제거 — 이 모든 것이 reduce 하나로 됩니다.

배열 전체를 하나의 결과로 합치는 방법은?

reduce — 배열을 순회하면서 하나의 값으로 줄여가는 메서드입니다. 가장 강력하지만 읽기 어려울 수 있습니다.


article

핵심 내용

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 체이닝에서 각 메서드의 역할 순서는?

key

핵심 용어

🔄

map

변환 — 형태를 바꿀 때 (5개 → 5개)

🔍

filter

추출 — 조건에 맞는 것만 (5개 → 2개)

🎯

find

검색 — 첫 번째 매칭 하나 (5개 → 1개)

📊

reduce

요약 — 하나의 값으로 (5개 → 1값)

edit_note

정리 노트

reduce & 체이닝 핵심 정리

reduce

reduce
배열을 하나의 값으로 요약하는 메서드 (합계, 최대값, 그룹핑 등)
누적값(acc)
이전 반복의 결과가 다음 반복에 전달되는 값
초기값
reduce의 두 번째 인자로 반드시 전달, 빈 배열 방어

체이닝 패턴

filter → map → reduce
추출 → 변환 → 요약 순서의 데이터 파이프라인
가독성
체이닝이 길어지면 중간 변수로 분리해서 의미를 명확하게

reduce는 강력하지만 복잡하니, 단순 합계/카운트 외에는 for...of를 고려하세요.

퀴즈와 인터랙션으로 더 깊이 학습하세요

play_circle인터랙티브 레슨 시작