-
[Functional] map, filter, reduceprograming/Language 2019. 7. 15. 18:27
안녕하세요, Einere입니다.
(ADblock을 꺼주시면 감사하겠습니다.)
2019/06/25 - [programing/JavaScript] - [Functional] 평가와 일급, 고차함수
2019/07/15 - [programing/JavaScript] - [Functional] 순회와 이터러블
2019/07/15 - [programing/JavaScript] - [Functional] 제네레이터와 이터러블
map
const products = [ {name: "볼펜", price: 500}, {name: "샤프", price: 1000}, {name: "자", price: 700}, {name: "커터칼", price: 1500}, {name: "수정테이프", price: 3000}, ]; // 함수와 이터레이터를 받아, 요소들을 순회하며, 특정 함수의 결과값을 배열에 채운 뒤 반환하는 함수 const map = (func, iter) => { let ret = []; for(const e of iter) { ret.push(func(e)); } return ret; }; const names = map(item => item.name, products); console.log(names); // ["볼펜", "샤프", "자", "커터칼", "수정테이프"] 출력 const prices = map(item => item.price, products); console.log(prices); // [500, 1000, 700, 1500, 3000] 출력
위의 map함수는 이터러블 프로토콜을 준수하므로, 범용성 및 사용성이 뛰어나다.
filter
const filter = (f, iter) { let arr = []; for(const e of iter) { if(f(e)) arr.push(e); } return arr; }; // 상품 객체 배열에서, 15000원 이상 상품 이름을 얻고자 하는 경우 const products = [ {name:'반팔티', price:12000}, {name:'긴팔티', price:15000}, {name:'청바지', price:30000}, {name:'야구모자', price:8000}, {name:'캔버스화', price:25000} ]; console.log(map(p => p.name, filter(p => p.price >= 15000, products))); // ['긴팔티', '청바지', '캔버스화'] 출력
배열에서 특정 요소를 걸러내고 싶은 경우 사용.
reduce
const reduce = (f, acc, iter) => { if(!iter) { iter = acc[Symbol.iterator](); acc = iter.next().value; } for(const e of iter) { acc = f(acc, e); } return acc; }; // 상품의 가격이 15000이상인 제품들의 총 합을 구하고 싶은 경우 const products = [ {name:'반팔티', price:12000}, {name:'긴팔티', price:15000}, {name:'청바지', price:30000}, {name:'야구모자', price:8000}, {name:'캔버스화', price:25000} ]; const add = (a, b) => a + b; console.log( reduce(add, map(p => p.price, filter(p => p.price >= 15000, products) ) ) ); // 70000 출력
배열에서 특정 연산을 수행하여 하나의 값을 얻고자 하는 경우 사용. (누산, 합계 등등..)
비동기 상황을 고려하면 다음과 같이 수정할 수 있습니다.
const reduce = curry(async (f, acc, iter) => { if (!iter) { iter = acc[Symbol.iterator](); acc = await iter.next().value; } for (const e of iter) { acc = await f(acc, e); } return acc; }); go(Promise.resolve(1), v => v + 10, v => new Promise((res, rej) => { setTimeout(() => { res(v + 100); }, 2000); }), v => Promise.reject('error~~'), v => v + 1000, console.log ).catch(result => console.log(result)); /* 출력 error~~ */
go함수는 reduce를 사용하므로, 결과 또한 promise가 됩니다. 따라서, catch를 체이닝하여 에러 핸들링을 할 수 있습니다.
참고
마이클 포거스, 『함수형 자바스크립트 : 새롭고 올바른 자바스크립트 프로그래밍 기법』, 한빛미디어(2014).
유인동, 인프런 - 함수형 프로그래밍과 JavaScript ES6+
'programing > Language' 카테고리의 다른 글
[JS] 함수선언식과 함수표현식 (0) 2019.07.16 [JS] JavaScript get call stack trace (0) 2019.07.16 [Functional] 제네레이터와 이터러블 (0) 2019.07.15 [Functional] 순회와 이터러블 (0) 2019.07.15 [Functional] 평가와 일급, 고차함수 (0) 2019.06.25 댓글