앞선 이터러블 프로토콜과 map을 공부하면서 사용자 정의로 이터러블한 객체를 순회하면서 값을 매핑했다.
const map = (f, iter) => {
const res = [];
for (const p of iter) {
res.push(f(p));
}
return res;
};
let m = new Map();
m.set('a', 10);
m.set('b', 20);
const it = m[Symbol.iterator]();
it.next();
it.next();
it.next();
map(([k, a]) => [k, a * 2], m);
이터러블을 따르는 객체는 임의로 만든 map 함수에 잘 작용하는 이터러블 객체이다.
filter 함수
const products = [
{ name: '허니버터칩', price: 1500 },
{ name: '벌집핏자', price: 1800 },
{ name: '치킨팝', price: 800 },
{ name: '에낙', price: 500 },
];
위와 같은 과자 객체 배열이 있을 때, 특정 금액 이하의 과자를 정제해서 사용하고자 한다면 아래와 같이 작성할 수 있다.
let under1000 = [];
for (const product of products) {
if (product.price < 1000) under1000.push(product);
}
...under1000
// { name: '치킨팝', price: 800 }
// { name: '에낙', price: 500 }
하지만 이는 filter 메서드를 사용하면 쉽게 찾아낼 수 있다.
under1000 = products.filter(product => product.price < 1000);
추가적으로 함수를 만들어 나타내면 아래와 같다.
const filter = (f, iter) => {
let res = [];
for (const of iter) {
if (f(a)) res.push(a);
}
return res;
};
이 로직을 사용해 값을 찾아낼 수 있다.
filter(p => p.price < 1000, products);
이는 이터러블 프로토콜을 따르는 모든 자료형에 있어 적용할 수 있는 함수로 다형성이 기존 filter 메서드보다 높다.
reduce
reduce는 값을 축약해나가는 함수이다.
const nums = [1, 2, 3, 4, 5];
이 nums라는 배열을 모두 더한 값을 알고자 할 때, 아래와 같이 작성해볼 수 있다.
let total = 0;
for (const n of nums) {
total += n;
}
이를 reduce함수를 새로 만들어 간소화할 수 있다.
const reduce = (f, acc, iter) => {
for (const a of iter) {
acc = f(acc, a);
}
return acc;
};
reduce는 아래 처럼 작동하는 것으로 볼 수 있다.
const add = (a, b) => a + b;
add(add(add(add(add(0, 1), 2), 3), 4), 5);
acc(더한 값)을 생략해도 구할 수 있도록 아래처럼 코드를 바꿔 사용할 수 있다.
const reduce = (f, acc, iter) => {
if (!iter) {
iter = acc[Symbol.iterator]();
acc = iter.next().value;
}
for (const a of iter) {
acc = f(acc, a);
}
return acc;
};
iter 매개변수 자리에 인자가 오지 않을 때, 이터레이터로 값을 한 번 순회하고, 해당 이터레이터에서의 value를 뽑아낸다.
그리고, 보조함수에게 로직을 맡긴다.
슬슬 어떻게 함수형 프로그래밍을 할 수 있는지 감이 오는 것 같다. 기존의 자바스크립트에서 정적 메서드들이 내부적으로 어떻게 구현이 되어 있을지 궁금했는데 이번 기회에 대략적으로 알 수 있었다. 내가 애용하는 이런 메서드들이 실은 그렇게 어렵지 않게 구현되어 있던 것도 신기한 사실이었다.
'프론트엔드 > JS' 카테고리의 다른 글
[JavaScript] go, pipe로 읽기 좋은 코드 만들기 (0) | 2023.04.27 |
---|---|
[JavaScript] Map + Filter + Reduce 중첩 사용과 함수형 사고 (0) | 2023.04.27 |
[JavaScript] Map 메서드와 함수형 프로그래밍, 다형성 (2) | 2023.04.23 |
[JavaScript] ES6에서의 순회와 이터러블 (2) | 2023.04.22 |
[JavaScript] Number, Math (0) | 2022.09.27 |