const product = [
{ name: '반팔티', price: 15000, quantity: 1 },
{ name: '긴팔티', price: 20000, quantity: 2 },
{ name: '핸드폰케이스', price; 15000, quantity: 3 },
{ name: '후드티', price: 30000, quantity: 4 },
{ name: '바지', price: 25000, quantity: 5 },
];
const go = (...args) => reduce((a, f) => f(a), args);
여기서 수량을 모두 합하고자 할 때, go를 통해 연속적으로 함수를 실행할 수 있다.
go(
products,
map(p => p.quantity),
console.log
);
위의 결과는 [1, 2, 3, 4, 5]라는 결과로 귀결된다.
이때, 정수형 배열이 반환되었기 때문에 reduce를 통해서 총 합을 계산할 수 있다.
go(
products,
map(p => p.quantity),
reduce((a, b) => a + b),
console.log
);
결과로는 15의 총합이 나오는 것을 볼 수 있다.
이를 함수로써 사용할 수 있다. 예를 들어서 quantity를 키로 가지는 객체 배열에 대해서는 동일한 로직으로 처리하여 총합을 계산하는 함수를 완성할 수 있다.
products가 첫 번째 인수로 이 자리를 새로운 함수의 인자로서 전달하면 되기 때문이다.
const total_quantity = products => go(products,
map(p => p.quantity),
reduce((a, b) => a + b);
이때, go의 첫 번째 인자로 products를 넣는다는 것은 기존에 만들었던 pipe 함수로도 대체할 수 있음을 보여준다.
const pipe = (...fs) => (a) => go(a, ...fs);
const total_quantity = pipe(
map(p => p.quantity),
reduce((a, b) => a + b));
console.log(total_quantity(products));
위처럼 pipe는 내가 원하는 시점에 실행시킬 수 있는 함수이기 때문에, 첫 번째로 함수들을 받아놓은 다음, products를 인자로 하여 원하는 로직을 수행할 수 있다.
간단하게 응용하여, 수량과 가격을 합산해 총 값을 계산할 수도 있다.
const total_price = pipe(
map(p => p.price * p.quantity),
reduce((a, b) => a + b));
console.log(total_price(products));
이때, total_quantity와 total_price는 map과 reduce가 겹친다. 또한, 이 두 개의 함수는 특정 도메인에 종속된 함수이기 때문에 조금 더 추상화 레벨을 높이는 것이 좋다.
const add = (a, b) => a + b;
const sum = (f, iter) => go(
iter,
map(f),
reduce(add));
console.log(sum(p => p.quantity, products));
조금 더 추상화를 하기 위해, map안에 들어가는 함수를 매개변수로 만들어서 원하는 함수를 집어 넣을 수 있다. 즉, 최종적으로 sum을 사용하면 아래와 같이 작성할 수 있다.
const total_quantity = products => sum(p => p.quantity, products)
console.log(total_quantity(products));
const total_price = products => sum(p => p.quantity * p.price, products);
console.log(total_price(products));
그런데 심지어 여기서 더 코드를 간결하게 할 수 있다. curry를 사용하는 방법이다.
const sum = curry((f, iter) => go(
iter,
map(f),
reduce(add)));
const total_quantity = products =>
sum(p => p.quantity)(products);
여기서 products를 받아서 그 인자를 다시 반환하는 함수의 인자로써 사용하기 때문에 단순히 우리가 원하는 함수만을 전달해 사용할 수 있다.
const total_quantity = sum(p => p.quantity);
const total_price = sum(p => p.price * p.quantity);
currying을 통해서 보조함수를 사용하겠다는 것으로 코드를 간결하게 만들 수 있다.
출처: 인프런 함수형 프로그래밍과 JavaScript ES6+
'프론트엔드 > JS' 카테고리의 다른 글
[JavaScript] range와 느긋한 L.range 테스트 (0) | 2023.05.01 |
---|---|
[JavaScript] range와 느긋한 L.range (0) | 2023.04.30 |
[JavaScript] go, curry 함수를 만들어 읽기 좋은 코드 만들기 (0) | 2023.04.29 |
[JavaScript] go, pipe로 읽기 좋은 코드 만들기 (0) | 2023.04.27 |
[JavaScript] Map + Filter + Reduce 중첩 사용과 함수형 사고 (0) | 2023.04.27 |