Node.js/JS

[JavaScript] 이터러블 프로토콜과 map, filter, reduce

턴태 2023. 4. 25. 23:15

앞선 이터러블 프로토콜과 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를 뽑아낸다.

그리고, 보조함수에게 로직을 맡긴다.


슬슬 어떻게 함수형 프로그래밍을 할 수 있는지 감이 오는 것 같다. 기존의 자바스크립트에서 정적 메서드들이 내부적으로 어떻게 구현이 되어 있을지 궁금했는데 이번 기회에 대략적으로 알 수 있었다. 내가 애용하는 이런 메서드들이 실은 그렇게 어렵지 않게 구현되어 있던 것도 신기한 사실이었다.