• Blog

  • Snippets

함수형 반복

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
}
)
}

# 정리