Skip to content

함수형 반복

함수형 프로그래밍은 잘 동작하는 작은 추상화 함수로 되어 있습니다.

이번 글에서는 가장 많이 사용하는 함수형 도구인 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는 항목을 조합해 최종 값을 만듭니다.