함수형 반복
June 18, 2024
쏙쏙들어오는 함수형 코딩
# 기존 코드 forEach()로 바꿔보기
function emailsForCustomers(customers, goods, bests){let emails = [];for(let i = 0; i < costomers.length ; i ++){let customer =customers[i];let email = emailForCustomer(customer, goods, bests)emails.push(email);}return email;}
forEach()로 변경
function emailsForCustomers(customers, goods, bests){let emails = [];forEach(customers, function(customer){let email = emailForCustomer(customer, goods, bests)emails.push(email);});return emails;}
# 예제를 통해 map()함수 도출하기
팀에 할당된 코드 중 비슷한 코드들function emailsForCustomers(customers, goods, bests){let emails = [];forEach(customers, function(customer){let email = emailForCustomer(customer, goods, bests)emails.push(email);});return emails;}function biggestPurchasePerCustomer(customers){let purchases = [];forEach(customers, function(costomer){let purchase = biggestPurchase(customer)purchase.push(purchase);});return purchases;}function customerFullNames(customers){let fullNames = [];forEach(customers, function(customer){let name = customer.firstName + ' ' + customer.lastName;fullNames.push(name);});return fullNames}function customerCities(customers){let cities = [];forEach(customers, function(customer){let city = customer.address.city;cities.push(city);});return cities;}
결과 배열에 넣을 값을 만드는 부분만 다르다.
함수 본문을 콜백으로 바꾸기 리팩터링으로 일반화할 수 있다.
콜백으로 바꾼 버전
function emailsForCustomers(customers, goods, bests){return map(customers, function(customer){return emailForCustomer(customer, goods, bests)})}function map(array, f){let newArray = [];forEach(array, function(element){newArray.push(f(element));});return newArray}
# 함수형 도구 Map()
function map(array, f){let newArray = [];forEach(array, function(element){newArray.push(f(element));});return newArray;}
Map()
은 X
(어떤 값의 집합)값이 있는 배열을 Y(또 다른 값의 집합)값이 있는 배열로 반환한다고 볼 수 있다.
Map()
은 값 하나를 바꾸는 함수를 배열 전체를 바꾸는 데 사용할 수 있다.
function emailsForCustomers(customers, goods, bests){return map(customers, function(customer){return emailForCustomer(customer, goods, bests)})}
# 함수를 전달하는 세 가지 방법
전역으로 정의하기
함수를 전역적으로 정의하고 이름 붙일 수 있다.
가장 많이 쓰는 방법:
function greet(name){ // 프로그램 한 곳에 이름을 붙여 함수를 정의return "Hello, " + name;}let friendGreetings = map(friendsNames, greet)// 어디서나 이름으로 함수를 참조할 수 있다.// 이렇게 map()에 전달할 수 있다.
지역적으로 정의하기
지역 범위 안에서 정의하고 이름을 붙일 수 있다.
이름을 가지고 있지만, 범위 밖에서는 사용할 수 없다.
지역적으로 쓰고 싶지만 이름이 필요할 때 유용
function greetEverybody(friends){// 이 함수 범위 안에 있다.let greeting;if(language === 'english'){greeting = 'Hello, ';} else {greeting = 'Salut, ';}// 이 함수 안에서 이름을 붙여 함수를 정의let greet = function(name){return greeting + name;};// 같은 범위에 있다면 이름으로 함수를 참조할 수 있다.return map(friends, greet)}
인라인으로 정의하기
함수를 사용하는 곳에서 바로 정의할 수 있다.
함수를 변수 같은 곳에 넣지 않기 때문에 이름이 없다.
익명함수
라고 부른다. 문맥에서 한 번만 쓰는 짧은 함수에 쓰면 좋다.
let friendGreetings = map(friendsNames, function (name){return 'Hello, ' + name;});
# 예제를 통해 Filter()함수 도출하기
function selectBestCustomers(customers){let newArray = [];forEach(customers, function(customer){//앞부분if(customer.purchases.length >= 3) //본문newArray.push(customer);//뒷부분});return newArray;}function selectCustomerAfter(customers, date){let newArray = [];forEach(customers, function(customer){//앞부분if(customer.signupDate > date) //본문newArray.push(customer);//뒷부분});return newArray;}function selectCustomerBefore(customers, date){let newArray = [];forEach(customers, function(customer){//앞부분if(customer.signupDate < date) //본문newArray.push(customer);//뒷부분});return newArray;}function singlePurchaseCustomers(customers){let newArray = [];forEach(customers, function(customer){//앞부분if(customer.purchases.length === 1) //본문newArray.push(customer);//뒷부분});return newArray;}
function selectBestCustomers(customers){return filter(customers, funtion(customer){return customer.purchase.length >= 3;// 표현식을 함수로 빼서 인자로 전달})}function filter(array, f){let newArray = [];forEach(array, function(element){if(f(element)) // 조건식으로 콜백을 호출newArray.push(element);});return newArray;}
# 함수형 도구 Filter()
function filter(array, f){let newArray = []; // 빈 배열 생성forEach(array, function(element){if(f(element)) // f()를 호출해 항목을 결과 배열에 넣을지 확인newArray.push(element);// 조건에 맞으면 원래 항목을 결과 배열에 넣음});return newArray; // 결과 배열 리턴}
filter()는 배열에서 일부 항목을 선택하는 함수로 볼 수 있다.
항목이 x
인 배열에 filter()를 사용해도 결과는 여전히 항목이 x
인 배열
# 함수형 도구 Reduce()
function reduce(array, init, f){let accum = init;forEach(array, function(element){accum = f(accum,element)});return accum;}
reduce()는 배열을 순회하면서 값을 누적
값을 누적하는 것은 추상적인 개념
실제로는 여러 가지 형태가 될 수 있다.
예를 들면 값을 더할 수도 있고, 해시 맵이나 문자열을 합치는 것이 될 수도 있다.
function countAllPurchases(customers){return reduce(customers, 0, function (total, customer){return total + customer.purchase.length})}
# 정리
- Map(), Filter(), Reduce()에 대해 알아봤다.
- Map(), Filter(), Reduce()는 특별한 방법으로 배열을 반복할 수 있다.
- 반복문을 대체해서 코드의 목적을 더 명확하게 할 수 있다.
- Map()은 어떤 배열의 모든 항목에 함수를 적용해 새로운 배열로 바꾼다.
- 각 항목은 지정한 콜백 함수에 의해 변환한다.
- Filter()는 어떤 배열의 하위 집합을 선택해 새로운 배열로 만든다.
- 술어를 전달해서 특정 항목을 선택할 수 있다.
- Reduce()는 초깃값을 가지고 어떤 배열의 항목을 조합해 하나의 값을 만든다.
- 데이터를 요약하거나 시퀀스를 하나의 값으로 만들 때 주로 쓴다.