이 글은 유인동님의 함수형 프로그래밍 강의내용을 정리한 글입니다.
map, filter, reduce 함수들을 매우 유용한 함수들이다. 하지만 배열에서만 사용할 수 있다.
자바스크립트의 환경에서는 배열은 아니더라도 많은 api의 헬퍼 함수들과 값들이 이터러블 프로토콜을 따른다.
따라서 map, filter, reduce 함수들을 이터러블 프로토콜을 따르게 구현하여 사용하면 개발할 때 유용하게 사용할 수 있다.
예를들어 querySelectorAll
메서드로 노드들을 불러오면 배열이 아닌 이터러블 객체인데 이 때 이 노드들을 값으로 하는 이터러블 객체에 map, filter, reduce와 같은 함수들을 적용하게 해보자.
이터러블의 모든 요소를 돌면서 매핑되는 요소들의 값으로 새로운 배열로 리턴한다.
const map = (f, iter) => {
const res = [];
for (const el of iter) {
res.push(f(el));
}
return res;
};
const products = [
{ name: '반팔티', price: 15000 },
{ name: '긴팔티', price: 20000 },
{ name: '핸드폰케이스', price: 15000 },
{ name: '후드티', price: 30000 },
{ name: '바지', price: 25000 },
];
console.log(map(p => p.name, products));
// ["반팔티", "긴팔티", "핸드폰케이스", "후드티", "바지"]
console.log(map(p => p.price, products));
// [15000, 20000, 15000, 30000, 25000]]
이터러블의 모든 요소를 돌면선 조건에 맞는 요소만 걸러서 새로운 배열로 리턴한다.
const filter = (f, iter) => {
let res = [];
for (const a of iter) {
if (f(a)) res.push(a);
}
return res;
};
const products = [
{ name: '반팔티', price: 15000 },
{ name: '긴팔티', price: 20000 },
{ name: '핸드폰케이스', price: 15000 },
{ name: '후드티', price: 30000 },
{ name: '바지', price: 25000 },
];
console.log(...filter(p => p.price < 20000, products));
// {name: "반팔티", price: 15000}
// {name: "핸드폰케이스", price: 15000}
console.log(...filter(p => p.price >= 20000, products));
// {name: "긴팔티", price: 20000}
// {name: "후드티", price: 30000}
// {name: "바지", price: 25000}
이터러블의 모든 요소의 값을 하나의 값으로 (누적하여) 축약한 값을 리턴한다.
const reduce = (f, acc, iter) => {
if (!iter) { // acc는 옵셔널로 예외처리
iter = acc[Symbol.iterator]();
acc = iter.next().value;
}
for (const a of iter) {
acc = f(acc, a);
}
return acc;
};
const products = [
{ name: '반팔티', price: 15000 },
{ name: '긴팔티', price: 20000 },
{ name: '핸드폰케이스', price: 15000 },
{ name: '후드티', price: 30000 },
{ name: '바지', price: 25000 },
];
console.log(reduce((a, b)=> a + b, 0, [1, 2, 3, 4, 5]));
// 15
console.log(reduce((a, b)=> a + b, [1, 2, 3, 4, 5]));
// 15
console.log(
reduce((total_price, product) => total_price + product.price, 0, products)
);
// 105000
const products = [
{ name: '반팔티', price: 15000 },
{ name: '긴팔티', price: 20000 },
{ name: '핸드폰케이스', price: 15000 },
{ name: '후드티', price: 30000 },
{ name: '바지', price: 25000 },
];
console.log(map(p => p.price, products));
// [15000, 20000, 15000, 30000, 25000]
console.log(filter(price => price < 20000, map(p => p.price, products)));
// [15000, 15000]
const add = (a, b) => a + b;
console.log(
reduce(
add,
map(
p => p.price,
filter(p => p.price < 20000, products)
)
)
);
// 30000
console.log(
reduce(
add,
filter(
n => n >= 20000,
map(p => p.price, products)
)
)
);
// 75000
문장의 해석은 오른쪽에서 왼쪽으로 읽어나가면 된다.
20000원 미만 아닌가요??!