map 아래의 함수는 이터러블에 사용 가능하게 작성된 map 함수이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const products = [ { name : "반팔티" , price : 15000 }, { name : "긴팔티" , price : 20000 }, { name : "핸드폰케이스" , price : 15000 }, { name : "후드티" , price : 30000 }, { name : "바지" , price : 25000 }, ]; const map = (f, iter ) => { let res = []; for (const p of iter) { res.push(f(p)); } return res; }; console .log(map((p ) => p.name, products));console .log(map((p ) => p.price, products));
filter 아래의 함수는 이터러블에 사용 가능하게 작성된 filter 함수이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 const products = [ { name : "반팔티" , price : 15000 }, { name : "긴팔티" , price : 20000 }, { name : "핸드폰케이스" , price : 15000 }, { name : "후드티" , price : 30000 }, { name : "바지" , price : 25000 }, ]; const filter = (f, iter ) => { let res = []; for (const a of iter) { if (f(a)) res.push(a); } return res; }; log(...filter((p ) => p.price < 20000 , products)); console .log(filter((p ) => p.price >= 20000 , products));log(filter((n ) => n % 2 , [1 , 2 , 3 , 4 ])); log( filter( (n ) => n % 2 , (function * ( ) { yield 1 ; yield 2 ; yield 3 ; yield 4 ; yield 5 ; })() ) );
reduce 아래의 함수는 이터러블에 사용 가능하게 작성된 filter 함수이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 const nums = [1 , 2 , 3 , 4 , 5 ];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; }; const add = (a, b ) => a + b;console .log(reduce(add, 0 , [1 , 2 , 3 , 4 , 5 ]));console .log(add(add(add(add(add(0 , 1 ), 2 ), 3 ), 4 ), 5 ));console .log(reduce(add, [1 , 2 , 3 , 4 , 5 ]));
단순 숫자 계산이 아니여도 활용할 수 있다. 아래는 products배열의 price를 더하는 코드이다.(다형성)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 const products = [ { name : "반팔티" , price : 15000 }, { name : "긴팔티" , price : 20000 }, { name : "핸드폰케이스" , price : 15000 }, { name : "후드티" , price : 30000 }, { name : "바지" , price : 25000 }, ]; 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; }; console .log( reduce((total_price, product ) => total_price + product.price, 0 , products) );
다형성 위에서 작성한 map,filter,reduce함수는 이터러블 프로토콜을 따르는 객체에 전부 적용할 수 있다. 관련된 연산자도 사용할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const map = (f, iter ) => { let res = []; for (const p of iter) { res.push(f(p)); } return res; }; console .log(document .querySelectorAll("*" ).map((ele ) => ele.nodeName));console .log(map((el ) => el.nodeName, document .querySelectorAll("*" )));function * gen ( ) { yield 2 ; yield 3 ; yield 4 ; } console .log( map((a ) => a * a), gen() );
제너레이터 또한 이터러블 프로토콜을 따르기 때문에 제너레이터에도 적용할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const map = (f, iter ) => { let res = []; for (const p of iter) { res.push(f(p)); } return res; }; function * gen ( ) { yield 2 ; yield 3 ; yield 4 ; } console .log( map((a ) => a * a), gen() );
마찬가지로 map과 set에도 적용할 수 있다.
1 2 3 4 5 let m = new Map ();m.set("a" , 10 ); m.set("b" , 20 ); console .log(new Map (map(([k, a] ) => [k, a * 2 ], m)));
Ref 함수형 프로그래밍과 JavaScript ES6+