자바스크립트 배열 메서드 map filter reduce 완벽 정리
자바스크립트 배열 메서드 map filter reduce, 한 번에 이해하기
자바스크립트 배열 메서드 map filter reduce는 반복문(for) 대신 데이터를 변환하고 걸러내고 합치는 데 쓰이는 핵심 도구입니다. 세 메서드 모두 원본 배열을 바꾸지 않고(불변) 새 값을 만들어 낸다는 공통점이 있습니다. 차이는 "무엇을 만드는가"입니다: map은 같은 길이의 새 배열, filter는 조건에 맞는 일부만 모은 배열, reduce는 하나의 최종 값입니다.
한눈에 보는 차이
| 메서드 | 역할 | 반환값 |
|---|---|---|
| map | 각 요소를 변환 | 같은 길이의 새 배열 |
| filter | 조건에 맞는 요소만 선택 | 더 짧거나 같은 새 배열 |
| reduce | 모든 요소를 하나로 누적 | 임의의 단일 값(숫자, 객체 등) |
map: 모든 요소를 변환하기
map은 배열의 각 요소에 함수를 적용해 같은 개수의 새 배열을 만듭니다.
const nums = [1, 2, 3, 4];
const doubled = nums.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8]
console.log(nums); // [1, 2, 3, 4] (원본 그대로)
// 객체 배열에서 특정 속성만 뽑기
const users = [{ name: '민수' }, { name: '지영' }];
const names = users.map(u => u.name);
console.log(names); // ['민수', '지영']filter: 조건에 맞는 것만 남기기
filter는 콜백이 true를 반환하는 요소만 모아 새 배열을 만듭니다. 길이는 같거나 짧아집니다.
const nums = [1, 2, 3, 4, 5, 6];
const evens = nums.filter(n => n % 2 === 0);
console.log(evens); // [2, 4, 6]
const products = [
{ name: '키보드', price: 30000 },
{ name: '마우스', price: 15000 },
];
const cheap = products.filter(p => p.price < 20000);
console.log(cheap); // [{ name: '마우스', price: 15000 }]reduce: 하나의 값으로 합치기
reduce는 가장 강력하지만 처음엔 헷갈리는 메서드입니다. 누적값(accumulator)과 현재 요소(current)를 받아, 매 단계 누적값을 갱신해 마지막에 하나의 값을 만듭니다. 두 번째 인자로 초기값을 주는 것이 안전합니다.
const nums = [1, 2, 3, 4];
// 합계: 초기값 0
const sum = nums.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 10
// 객체로 그룹핑
const fruits = ['사과', '배', '사과', '배', '사과'];
const count = fruits.reduce((acc, fruit) => {
acc[fruit] = (acc[fruit] || 0) + 1;
return acc;
}, {});
console.log(count); // { 사과: 3, 배: 2 }세 메서드 체이닝하기
이들은 모두 배열을 반환하므로(reduce는 결과에 따라) 자연스럽게 이어 붙일 수 있습니다.
const orders = [
{ item: '커피', price: 4500, paid: true },
{ item: '케이크', price: 6000, paid: false },
{ item: '차', price: 4000, paid: true },
];
const totalPaid = orders
.filter(o => o.paid) // 결제된 것만
.map(o => o.price) // 가격만 추출
.reduce((acc, p) => acc + p, 0); // 합산
console.log(totalPaid); // 8500흔한 실수
- map에서 return 누락: 화살표 함수에 중괄호
{}를 쓰면return을 명시해야 합니다. 빠뜨리면undefined배열이 됩니다. - filter와 map 혼동: filter의 콜백은 "포함할지" 여부(boolean)를 반환해야 합니다. 값을 변형해 반환하면 의도와 다르게 동작합니다.
- reduce 초기값 생략: 빈 배열에서 초기값 없이 reduce를 호출하면
TypeError가 발생합니다. 초기값을 꼭 주세요. - 부수효과(side effect) 용도로 map 사용: 단순 반복(콘솔 출력 등)에는 반환값이 필요 없는
forEach가 적합합니다.
자주 묻는 질문
Q1. map과 forEach의 차이는 무엇인가요?
map은 변환한 결과로 새 배열을 반환하고, forEach는 반환값 없이 단순히 각 요소를 순회만 합니다. 새 배열이 필요하면 map, 출력처럼 결과가 필요 없으면 forEach를 쓰세요.
Q2. reduce로 map과 filter를 모두 대체할 수 있나요?
이론적으로는 가능합니다. 하지만 가독성이 떨어집니다. 변환은 map, 선별은 filter, 누적/집계는 reduce처럼 의도가 드러나는 메서드를 쓰는 것이 좋습니다.
Q3. 원본 배열이 바뀌나요?
아니요. map, filter, reduce는 원본 배열을 변경하지 않습니다. 다만 콜백 안에서 객체의 속성을 직접 수정하면 그 객체는 변할 수 있으니 주의하세요.