장바구니에 담긴 총 수량을 뽑아보는 코드를 작성해보자.
모든 quantity를 더해야 하기 때문에 products를 출발해서 quantity만 남겨놓으면 reduce를 통해서 축약하기 쉬울 것이다.
<script>
const products = [
{ name: '반팔티', price: 15000, quantity: 1, is_selected: true },
{ name: '긴팔티', price: 20000, quantity: 2, is_selected: false },
{ name: '핸드폰케이스', price: 15000, quantity: 3, is_selected: true },
{ name: '후드티', price: 30000, quantity: 4, is_selected: false },
{ name: '바지', price: 25000, quantity: 5, is_selected: false }
];
products 통해서 map을 해서 출력을 하게되면 아래와 같이 나오게 된다.
<script>
const products = [
{ name: '반팔티', price: 15000, quantity: 1, is_selected: true },
{ name: '긴팔티', price: 20000, quantity: 2, is_selected: false },
{ name: '핸드폰케이스', price: 15000, quantity: 3, is_selected: true },
{ name: '후드티', price: 30000, quantity: 4, is_selected: false },
{ name: '바지', price: 25000, quantity: 5, is_selected: false }
];
go(products,
map(p => p.quantity),
log);
</script>
그 다음에 go를 통해 map을 하고 reduce를 하면 a와 b를 받은 다음 a + b를 해주면 총 수량이 나타나게 된다.
go(products,
map(p => p.quantity),
reduce((a, b) => a + b),
log);
함수로 만들어보자. total_quantity라고 변수를 지정해주고 products가 들어오면 수량을 리턴해주는 함수를 만들어 볼 수 있다.
const total_quantity = products => go(products,
map(p => p.quantity),
reduce((a, b) => a + b));
log(total_quantity(products));
products를 받아서 products를 그대로 go에 넣는다는 것은 pipe로 되어도 된다는 것이다.
const total_quantity = pipe(
map(p => p.quantity),
reduce((a, b) => a + b));
log(total_quantity(products));
이번에는 price와 quantity가 연결되어서 합산되어지는 총 가격을 구하는 코드를 작성하자. 이 코드 또한 위와 거의 비슷할 것이다. total_price라는 함수가 있다고 하고 p.price * p.quantity를 한 값을 똑같이 reduce해준다.
const total_price = pipe(
map(p => p.price * p.quantity),
reduce((a, b) => a + b));
log(total_price(products));
그리고 reduce의 a+b 부분을 add라는 함수를 만들어서 간단하게 할 수 있다.
const add = (a, b) => a + b;
const total_quantity = pipe(
map(p => p.quantity),
reduce(add));
log(total_quantity(products));
const total_price = pipe(
map(p => p.price * p.quantity),
reduce(add));
log(total_price(products));
그리고 map이 전달하는 부분을 제외하고는 두 개의 코드가 동일한 코드이다. 추상화를 시켜보자. sum이라는 함수를 만들어본다. 함수와 f 이터레이터 iter을 받아서 go를 하면서 비슷한 일을 한다. map에 있는 부분을 위임을 한다.( map(f) )
그래서 sum을 이용해서 두 함수를 간략하게 나타낼 수 있다.
const sum = (f, iter) => go(
iter,
map(f),
reduce(add));
log를 출력하는데 sum을 하면서 products를 주고 p를 받아서 p의 quantity를 하면 같은 결과가 나온다.
log(sum(p => p.quantity, products));
log(sum(p => p.price * p.quantity, products));
const total_quantity = products => sum(p => p.quantity, products);
log(total_quantity(products));
const total_price = products => sum(p => p.price * p.quantity, products);
log(total_price(products));
curry를 이용해서도 작성할 수 있다. 먼저 curry함수로 감싸준다.
const sum = curry((f, iter) => go(
iter,
map(f),
reduce(add)));
sum같은 경우에는 아래와 같이 실행할 수 있다. products를 받아서 product를 받는 함수가 sum이 return한 함수에 products를 전달하고만 있기 때문에 아래 코드를 간단하게 나타낼 수 있다. 훨씬 코드가 줄어든 것을 볼 수 있다.
sum이라는 함수에 currying을 이용해서 보조함수를 사용하겠다는 것만으로( map(f) ) 간결하게 코드를 작성했다.
const total_quantity = products => sum(p => p.quantity)(products);
const total_price = products => sum(p => p.price * p.quantity)(products);
const total_quantity = sum(p => p.quantity);
const total_price = sum(p => p.price * p.quantity)
sum은 products만을 위해서 사용되는 함수가 아니다. 아래와 같이 유저가 있고 유저의 나이를 다 더하는 코드를 작성하면 합해진 결과를 볼수 있다. 즉 sum은 추상화 레벨이 매우 높은 것이다.
log(sum(u => u.age, [
{ age: 30 },
{ age: 20 },
{ age: 10 },
]))
지금까지 sum을 이용해서 total_quantity와 total_price를 만들어 보았다.
<출처 : 유인동 함수형 프로그래밍과 JavaScript ES6+>
https://www.inflearn.com/course/functional-es6/dashboard
함수형 프로그래밍과 JavaScript ES6+ - 인프런 | 강의
ES6+와 함수형 프로그래밍을 배울 수 있는 강의입니다. 이 강좌에서는 ES6+의 이터러블/이터레이터/제너레이터 프로토콜을 상세히 다루고 응용합니다. 이터러블을 기반으로한 함수형 프로그래밍,
www.inflearn.com
'JavaScript > 함수형 프로그래밍과 JavaScript ES6+' 카테고리의 다른 글
range와 느긋한 range(지연성ⅰ) (0) | 2021.08.20 |
---|---|
HTML로 출력하기 (0) | 2021.08.19 |
함수 조합으로 함수 만들기 (0) | 2021.08.19 |
go + curry를 사용하여 더 읽기 좋은 코드로 만들기 (0) | 2021.08.19 |
go를 사용하여 읽기 좋은 코드로 만들기 (0) | 2021.08.19 |