함수형 반복
함수형 프로그래밍은 잘 동작하는 작은 추상화 함수로 되어 있습니다.
이번 글에서는 가장 많이 사용하는 함수형 도구인 map, filter, reduce에 대해서 알아보겠습니다.
스터디 회차: 11회차 (2025년 9월 4일)
함수형 도구: map()
예제를 통해 도출하기
tsx
function emailsForCustomers(customers, goods, bests) {
var emails = [];
for (var i = 0; i < customers.length; i++) {
var customer = customers[i];
var email = emailForCustomer(customer, goods, bests);
emails.push(email);
}
return emails;
}
function biggestPurchasePerCustomer(customers) {
var purchases = [];
for (var i = 0; i < customers.length; i++) {
var customer = customers[i];
var purchase = biggestPurchase(customer);
purchases.push(purchase);
}
return purchases;
}- 비슷한 부분이 많고 결과 배열에 넣을 값을 만드는 부분만 다릅니다.
- 이를 "함수 본문을 콜백으로 바꾸기 리팩토링"을 통해 개선할 수 있습니다.
tsx
function emailsForCustomers(customers, goods, bests) {
return map(customers, function (customer) {
return emailForCustomer(customer, goods, bests);
});
}
function map(array, f) {
var newArray = [];
forEach(array, function (element) {
newArray.push(f(element));
});
return newArray;
}- 본문은 콜백으로 전달합니다.
map의 특징
tsx
function map(array, f) {
var newArray = [];
forEach(array, function (element) {
newArray.push(f(element));
});
return newArray;
}- x값이 있는 배열을 y값이 있는 배열로 변환합니다.
- 변환에는 바꾸는 함수가 필요합니다.
- 값 하나를 바꾸는 함수를 배열 전체를 바꾸는데 사용할 수 있습니다.
함수를 인라인으로 정의하기
tsx
var friendGreetings = map(friendsNames, function (name) {
return "Hello, " + name;
});- 사용하는 곳에서 바로 정의할 수 있습니다.
- 한번만 쓰는 짧은 함수에 쓰입니다.
- 고차함수에 인자로 넘기는 함수의 경우, 인라인으로 정의하여 넘길 수 있습니다.
함수형 도구: filter()
예제를 통해 도출하기
tsx
function selectBestCustomers(customers) {
var newArray = [];
forEach(customers, function (customer) {
if (customer.purchases.length >= 3) newArray.push(customer);
});
return newArray;
}
function selectCustomersAfter(customers, date) {
var newArray = [];
forEach(customers, function (customer) {
if (customer.signupDate > date) newArray.push(customer);
});
return newArray;
}- if 문으로 검사하는 부분만 다릅니다.
- 검사하는 코드는 결과배열에 어떤 항목에 담을지 결정합니다.
- 이부분을 본문으로 하여 "함수 본문을 콜백으로 바꾸기 리팩토링"을 적용할 수 있습니다.
tsx
function selectBestCustomers(customers) {
return filter(customers, function (customer) {
return customer.purchases.length >= 3;
});
}
function filter(array, f) {
var newArray = [];
forEach(array, function (element) {
if (f(element)) newArray.push(element);
});
return newArray;
}- 표현식을 인자로 전달하고 조건식을 콜백으로 부릅니다.
filter의 특징
tsx
function filter(array, f) {
var newArray = [];
forEach(array, function (element) {
if (f(element)) newArray.push(element);
});
return newArray;
}- 배열에서 일부 항목을 선택하는 함수입니다.
- 남길 배열을 선택하기 때문에 원래 가진 항목보다 적을 수 있습니다.
- 항목을 선택하기 위한 불리언 타입을 리턴하는 함수를 전달해야합니다.
함수형 도구: reduce()
예제를 통해 도출하기
tsx
function countAllPurchases(customers) {
var total = 0;
forEach(customers, function (customer) {
total = total + customer.purchases.length;
});
return total;
}
function concatenateArrays(arrays) {
var result = [];
forEach(arrays, function (array) {
result = result.concat(array);
});
return result;
}- 변수의 초기값과 변수의 다음값을 구하는 계산 방법이 다릅니다.
- 이를 인자로 받아 개선할 수 있습니다.
tsx
function countAllPurchases(customers) {
return reduce(customers, 0, function (total, customer) {
return total + customer.purchase.length;
});
}
function reduce(array, init, f) {
var accum = init;
forEach(array, function (element) {
accum = f(accum, element);
});
return accum;
}reduce는 초기값하고 콜백함수를 인자로 받습니다.- 콜백함수는 현재값과 현재 항목에 대한 값을 인자로 전달 받습니다.
reduce의 특징
tsx
function reduce(array, init, f) {
var accum = init;
forEach(array, function (element) {
accum = f(accum, element);
});
return accum;
}- 배열을 순회하면서 값을 누적합니다.
- 함수는 현재값하고 반복하고 있는 현재 배열의 항목을 인자로 받습니다. 그리고 새로운 누적값을 리턴합니다.
- 인자의 수가 많기 때문에 인자의 순서에 유의해야합니다.
- 또한 초기값을 어떤 기준으로 결정할것인지 유의해야합니다.
정리하기
map은 모든 항목에 함수를 적용해 새로운 배열로 바꿉니다.filter는 하위 집합을 선택해 새로운 배열을 만듭니다.reduce는 항목을 조합해 최종 값을 만듭니다.
