본 시리즈는 인프런 강의 함수형 프로그래밍과 JavaScript ES6+ ( 지식 공유자 : 유인동 님 ) 의 강의를 수강하면서 내용을 제 방식대로 포스팅하는 글입니다.
이번에는 앞에서 만들었던 map, filter, reduce 함수를 함께 중첩해서 사용해 보는 코드를 작성해보자
앞의 내용을 건너뛰고 오신분들을 위해, 먼저 함수를 모듈화해서 정리해보겠습니다. ( 사실 내가 정리 해야해서,,, )
export function map(fn: (elem: any) => any, iter: Iterable<any>) {
let res = [];
for (const a of iter) {
res.push(fn(a));
}
return res;
}
export function filter(fn: (elem: any) => any, iter: Iterable<any>) {
let res = [];
for (const a of iter) {
if (fn(a)) res.push(a);
}
return res;
}
export function reduce(
fn: (result: any, data: any) => any,
acc: number | Iterable<any>,
iter?: Iterable<any> | Iterator<any>
) {
if (!iter) {
acc = acc as Iterable<any>;
iter = acc[Symbol.iterator]();
acc = iter.next().value;
}
for (const a of iter as Iterable<any>) {
acc = fn(acc, a);
}
return acc;
}
이제 데이터를 다뤄보며 응용해보자.
- 특정 금액 이하의 가격들을 뽑아서, 이 가격을 모두 합친 금액이 얼마인지 계산해보자.
const products = [
{ name: "반팔티", price: 15000 },
{ name: "긴팔티", price: 20000 },
{ name: "핸드폰케이스", price: 15000 },
{ name: "후드티", price: 30000 },
{ name: "바지", price: 25000 },
];
// 특정 금액 이하의 가격들을 뽑아서, 이 가격을 모두 합친 금액이 얼마인지 계산해보자.
// reduce 가 사용하는 보조함수 add()
const add = (a: number, b: number) => a + b;
const filterResult_1 = filter((product) => product.price < 20000, products); // [{ name: "반팔티", price: 15000 }, { name: "핸드폰케이스", price: 15000 }]
const mapResult_1 = map((product) => product.price, filterResult_1); // [15000, 15000]
const reduceResult_1 = reduce(add, mapResult_1); // 30000
const mapResult_2 = map((product) => product.price, products); // [15000, 20000, 15000, 30000, 25000]
const filterResult_2 = filter((price) => price < 20000, mapResult_2); // [15000, 15000]
const reduceResult_2 = reduce(add, filterResult_2); // 30000
// 위 아래의 결과가 동일한 30000원이 된다.
log(reduceResult_1);
log(reduceResult_2);
위의 코드를 연속해서 함수를 사용하는 형태로 작성하면 다음과 같다.
// 맨 안쪽 끝부터 읽기 시작하면 좀더 읽기 좋다.
log(
reduce(
add,
map(
(product) => product.price,
filter((product) => product.price < 20000, products)
)
)
);
log(
reduce(
add,
filter(
(price) => price < 20000,
map((product) => product.price, products)
)
)
);
함수형 프로그래밍 에서는 함수들을 중첩하고 연속해서 실행하면서 어떤 하나의 값으로 부터 출발해서 원하는 값으로 만들어 가는 형태로 사고를 하면 된다.
예를들어, 위의 상황에서 어떠한 데이터를 add 를 통해 reduce 를 하고 싶다면,
// 아래와 같은 형태까지는 별생각 없이 작성할수 있고
// log(reduce(add,
// ));
// 이 빈자리의 코드가 평가 되었을때 숫자가 있는 배열로 평가가 될것을 기대하면서
// reduce 와 add 를 작성하면, 잘 동작할 준비가 된 코드를 이미 작성할수 있다.
// 따라서 아래 배열 자리에 내가 어떠한 코드를 작성해야 한다고 생각하고 접근할수 있다.
log(reduce(add, [10, 20, 30, 40])); // 100
// map 을 통해서 숫자가 있는 배열이 평가 될것으로 기대하고 아래와 같이 작성할수 있다.
// reduce 또한 숫자 값으로 평가될것을 기대할수 있다.
log(reduce(add, map(product => product.price, products))); // === log(105000)
// 또한 products 역시 map 함수에서 추출 되기 전에 이자리에 들어올 데이터들을
// 특정 조건의 products 들만 평가되어져 있는 배열로 코드를 작성하면 되겠다 생각할수 있다.
log(
reduce(
add,
map((product) => product.price, products)
)
);
// 예를 들면 위의 products 배열에 아래와 같이 특정한 배열만 들어오게끔 하려면
log(
reduce(
add,
map(
(product) => product.price,
// products 자리에 아래와 같은 값이 평가되도록 기대하고,
// 이런 값이 평가될 코드를 작성한다고 생각하고 접근한다.
[
{ name: "반팔티", price: 15000 },
{ name: "핸드폰케이스", price: 15000 },
]
)
)
);
log(
reduce(
add,
map(
(product) => product.price,
filter((product) => product.price < 20000, products)
)
)
); // 30000
// filter 함수를 통해 기대하는 값을 평가해낼수 있다.
함수형 프로그래밍에서는 이런식으로 사고를 해가면서 프로그래밍을 한다.
'Javascript' 카테고리의 다른 글
reduce 를 이용한 함수 pipe() 를 구현해보자 - JS ES6+ 함수형 프로그래밍 - 19 (0) | 2022.09.28 |
---|---|
reduce 를 이용한 함수 go() 를 구현해보자 - JS ES6+ 함수형 프로그래밍 - 18 (0) | 2022.09.27 |
reduce 함수를 구현해보자 2 - JS ES6+ 함수형 프로그래밍 - 16 (0) | 2022.09.27 |
reduce 함수를 구현해보자 - JS ES6+ 함수형 프로그래밍 - 15 (2) | 2022.09.20 |
filter 함수를 구현해보자 - JS ES6+ 함수형 프로그래밍 - 14 (1) | 2022.09.12 |