목표 : Array.prototype에 정의되어 있는 map, reduce, filter 메서드를 이터러블 객체에서도 사용할 수 있도록 추상화해보자.
const arr = [1, 2, 3, 4, 5];
const newArr = arr.map((el) => el + 5);
console.log(newArr); // [6, 7, 8, 9, 10]
일반적인 이터러블 객체에서도 적용할수 있도록 map 함수를 다시 정의해보자.
const arr = [1, 2, 3, 4, 5];
const map = () => {
let newArr = [];
for (const num of arr) {
newArr.push(num);
}
return newArr;
};
console.log(map()); //[6, 7, 8, 9, 10]
위에서 정의한 map 함수는 외부의 arr
의 상태를 변경하는 부수효과가 생기므로 순수하지 못하다. 순수함수가 되도록 수정해보자.
const arr = [1, 2, 3, 4, 5];
const map = (target) => {
let res = [];
for (const el of target) {
res.push(el + 5);
}
return res;
};
console.log(map(arr)); //[6, 7, 8, 9, 10]
이렇게 순수함수로서 map을 정의하였다. 그러나 이 함수는 배열의 원소에 5를 더하는 것 외에는 활용할 수 없다. 따라서 재사용성을 높여줄 필요가 있다.
함수를 인자로 받게 하여 재사용성을 높여주자.
const arr = [1, 2, 3, 4, 5];
const map = (f, target) => {
let res = [];
for (const el of target) {
res.push(f(el));
}
return res;
};
console.log(map((el) => el + 5, arr)); // [6, 7, 8, 9, 10]
console.log(map((el) => el * 2, arr)); // [2, 4, 6, 8, 10]
이런 식으로 함수를 인자로 받게한다면 map함수의 재사용성을 높힐 수 있다.
우리의 목표는 일반적인 이터러블 객체에서도 배열에서와 비슷한 일을 하도록 하는 것이다.
우선, 제네레이터를 이용해서 이터러블 객체를 하나 만들고 위에서 정의한 map 함수를 적용해보자.
const set = new Set(["a", "b", "c", "d", "e"]);
const map = (f, iter) => {
let res = [];
for (const el of iter) {
res.push(f(el));
}
return res;
};
console.log(map((el) => el.toUpperCase(), set)); //["A", "B", "C", "D", "E"]
이렇게 정의한 map은 이터러블 객체에서도 활용할 수 있다.
const arr = [1, 2, 3, 4, 5];
const sum = arr.reduce((acc, currValue) => acc + currValue, 0);
console.log(sum); // 15
const arr = [1, 2, 3, 4, 5];
const reduce = (arr) => {
let sum = 0;
for (const num of arr) {
sum += num;
}
return sum;
};
console.log(reduce(arr)); //15
const arr = [1, 2, 3, 4, 5];
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;
const reduce = (f, acc, target) => {
for (const el of target) {
acc = f(acc, el);
}
return acc;
};
console.log(reduce(add, 0, arr)); //15
const reduce = (f, acc, iter) => {
if (!iter) {
iter = acc[Symbol.iterator]();
acc = iter.next().value;
}
for (const el of iter) {
acc = f(acc, iter);
}
return acc;
};