본문 바로가기
카테고리 없음

[JS] for문만 돌리던 내가 map, filter, reduce를 자유자재로 쓰게 된 계기

by 돌미나리는야생미나리 2026. 8. 5.

프런트엔드 개발을 처음 시작하고 자바스크립트(JavaScript)로 데이터를 다룰 때, 제 코드의 90%는 for문이나 forEach문으로 가득 차 있었습니다.

백엔드 API에서 받아온 리스트 데이터를 화면에 뿌려주거나, 특정 조건의 아이템만 걸러내고, 총합을 계산할 때도 항상 습관적으로 빈 배열을 하나 선언해 두고 for문을 돌리곤 했습니다.

동작은 잘 되었지만, 코드가 수십 줄로 길어지면서 변수가 오염되거나 가독성이 뚝 떨어지는 문제를 경험했습니다. 그러다 리액트(React)를 본격적으로 다루면서 map, filter, reduce 같은 고차 배열 함수의 진짜 위력을 깨닫게 되었습니다.

오늘은 제가 실무 및 프로젝트 코딩 중 for문 지옥에서 탈출해 배열 메서드 3대장을 실무에서 깔끔하게 활용하게 된 경험과 작성 팁을 정돈해 보려고 합니다.

1. map: 기존 배열을 변형해 새로운 UI 데이터 만들기

처음 리액트로 목록(List) 컴포넌트를 만들 때 map을 만나고 상당한 충격을 받았습니다.

기존에는 빈 배열을 만들어서 push()로 일일이 담아야 했던 작업이, map을 사용하니 원본 배열을 훼손하지 않으면서(불변성 유지) 가공된 새로운 배열을 반환해 주는 깔끔한 코드로 변했습니다.

JavaScript
 
// ❌ 옛날에 작성했던 지저분한 for문 방식
const rawUsers = [
  { id: 1, name: '김철수', age: 24 },
  { id: 2, name: '이영희', age: 29 },
];

const userNames = [];
for (let i = 0; i < rawUsers.length; i++) {
  userNames.push(rawUsers[i].name);
}

// ⭕ map을 활용해 단 한 줄로 깔끔하게 처리한 코드
const userNamesWithMap = rawUsers.map((user) => user.name);
// 결과: ['김철수', '이영희']

💡 실무 팁: 리액트 JSX 렌더링에서의 활용

리액트에서는 API로 받아온 객체 배열을 화면의 HTML 요소로 1:1 변환할 때 map이 필수적입니다. 고유한 key값만 잘 챙겨주면 선언적인 유려한 코드를 작성할 수 있습니다.

2. filter: 검색창과 조건별 필터링 기능 구현하기

쇼핑몰 카테고리 필터나 검색창 기능을 만들 때 가장 효자 역할을 해준 메서드가 바로 filter입니다.

조건식의 결과가 true인 요소들만 뽑아서 새로운 배열로 만들어주기 때문에, complex한 조건문 없이도 깔끔한 상태 업데이트가 가능해졌습니다.

JavaScript
 
const products = [
  { id: 1, name: '개발자 키보드', price: 150000, inStock: true },
  { id: 2, name: '버티컬 마우스', price: 75000, inStock: false },
  { id: 3, name: '모니터', price: 350000, inStock: true },
];

// ⭕ 재고가 있고(inStock), 가격이 20만원 이하인 상품만 필터링
const availableProducts = products.filter(
  (product) => product.inStock && product.price <= 200000
);
// 결과: [{ id: 1, name: '키보드', ... }]

체이닝 코드

3. reduce: 장바구니 총금액 계산과 데이터 그룹화의 최종병기

처음 reduce를 접했을 때는 (accumulator, currentValue) => ... 라는 생소한 문법 때문에 괜히 어렵게 느껴져 피하곤 했습니다.

하지만 장바구니에 담긴 상품들의 총결제 금액 계산이나 특정 기준에 따른 객체 데이터 그룹화를 처리할 때 reduce만큼 완벽한 도구가 없다는 것을 깨달았습니다.

JavaScript
 
const cartItems = [
  { name: '맥북 케이스', price: 35000, count: 2 },
  { name: 'C타입 젠더', price: 12000, count: 1 },
  { name: '장패드', price: 18000, count: 3 },
];

// ⭕ 장바구니 총금액을 한 번에 구하는 reduce
const totalPrice = cartItems.reduce((acc, item) => {
  return acc + item.price * item.count;
}, 0); // 초기값(initialValue)을 0으로 설정!

console.log(totalPrice); // 출력: 136000

💡 실무 팁: 초기값(0 또는 {})을 꼭 넣어주기

reduce를 사용할 때 가장 흔하게 범하는 실수가 두 번째 인자인 초기값을 빼먹는 것입니다. 빈 배열에서 초기값 없이 reduce를 호출하면 런타임 에러(TypeError)가 터질 수 있으므로, 습관적으로 초기값을 명시해 주는 것이 안전합니다.

4. 메서드 체이닝(Chaining)으로 완성하는 단단한 코드

map, filter, reduce의 진짜 매력은 이들을 사슬처럼 이어 붙이는 '메서드 체이닝'이 가능하다는 점입니다.

JavaScript
 
// ⭕ 재고 있는 상품 중 10만원 이상인 것들의 '총 가격'만 계산하기
const totalHighPriceInStock = products
  .filter((item) => item.inStock) // 1. 재고 있는 것만 추출
  .filter((item) => item.price >= 100000) // 2. 10만원 이상만 추출
  .reduce((acc, item) => acc + item.price, 0); // 3. 합계 계산

for문으로 작성했으면 20줄이 넘어갔을 로직이, 함수형 메서드를 이어 붙이니 단 몇 줄만으로 읽기 편한 코드가 되었습니다.

코드의 실행 결과

5. 회고 및 정리

for문 위주의 명령형 프로그래밍 방식에서 벗어나 자바스크립트의 고차 배열 함수들을 익히면서, 제 코드는 훨씬 선언적(Declarative)이고 가독성이 높은 코드로 발전할 수 있었습니다.

단순히 동작하는 코드를 넘어서 '읽기 편하고 유지보수하기 쉬운 코드'를 고민 중이신 자바스크립트 초보 개발자분들이라면, 오늘 당장 map, filter, reduce 체이닝 연습부터 시작해 보시길 권해드립니다!