함수형 도구 체이닝
- 13.1 함수형 도구 체이닝
- 13.2 체인을 명확하게 만드는 방법
- 13.3 반복문을 함수형 도구로 바꾸기
- 13.4 체이닝의 디버깅
- 13.5 다양한 함수형 도구들
map, filter, reduce를 하나씩 쓰면 for 루프 대체 정도지만, **여러 개를 연결(체이닝)**하면 복잡한 데이터 변환을 선언적으로 표현할 수 있어.
MegaMart에서 이런 요구사항이 온다고 해봐: "VIP 고객 중에서, 최근 한 달 이내에 구매한 사람들의 이메일 목록을 뽑아줘." 명령형으로 작성하면 중첩된 if문과 for 루프로 가득 차겠지만, 함수형 도구를 체이닝하면:
customers
.filter(isVIP)
.filter(isRecentPurchase)
.map(getEmail);
각 단계가 무엇을 하는지 바로 읽히잖아: VIP 필터 → 최근 구매 필터 → 이메일 추출.
체인이 길어지면 읽기 어려워질 수 있는데, 저자가 제안하는 방법이 있어. 첫째, 단계에 이름 붙이기 — 중간 결과에 의미 있는 이름을 붙이면 각 단계가 명확해지거든:
var vips = filter(customers, isVIP);
var recentVIPs = filter(vips, isRecentPurchase);
var emails = map(recentVIPs, getEmail);
둘째, 콜백에 이름 붙이기 — 익명 함수 대신 이름이 있는 함수를 쓰면 체인 자체가 문장처럼 읽혀. 셋째, 두 단계를 하나로 합치기 — filter를 두 번 하는 대신 조건을 합칠 수도 있지만, 너무 합치면 각 단계의 의미가 흐려지니 적절히 판단해야 해.
기존 for 루프를 함수형 도구로 바꾸는 방법도 있어. for 루프 안에서 if가 있으면 filter, 변환이 있으면 map, 누적이 있으면 reduce야. 이 패턴을 눈에 익히면 기계적으로 변환할 수 있거든.
체인이 기대한 결과를 안 낼 때 디버깅하는 방법도 알아야 해. tap 함수를 쓰거나 각 단계의 결과를 변수에 담아서 하나씩 확인하면 돼. 체이닝의 좋은 점이 여기 있어 — 각 단계가 독립적인 계산이라서 중간에 끊어서 확인하기 쉽거든.
function tap(value, fn) {
fn(value);
return value;
}
map, filter, reduce 외에도 유용한 함수형 도구들이 있어. pluck은 객체 배열에서 특정 필드만 뽑기(map의 특수 케이스), concatMap / flatMap은 map 후 flatten, groupBy는 특정 기준으로 그룹핑, sortBy는 특정 기준으로 정렬, take / drop은 앞에서 n개 가져오기/버리기, zip은 두 배열을 쌍으로 묶기야. 이런 도구들은 대부분 reduce로 구현 가능하지만, 자주 쓰는 패턴에 이름을 붙여 두면 코드가 더 읽기 쉬워져.
정리
13장 읽고 기억할 거 세 가지:
- 체이닝 = map/filter/reduce를 연결해서 복잡한 데이터 변환을 선언적으로 표현. 각 단계가 "무엇을" 하는지 바로 읽힌다
- 체인을 명확하게 만드는 핵심은 이름 붙이기. 중간 변수에 이름, 콜백에 이름을 붙이면 문장처럼 읽힌다
- for 루프를 함수형으로 바꾸는 법: if → filter, 변환 → map, 누적 → reduce. 이 패턴만 기억하면 기계적으로 변환 가능