JavaScript/함수형 프로그래밍과 JavaScript ES6+ 32

이터러블 중심 프로그래밍 실무적인 코드

위에 코드와 완전 같은 일을 하는데 데이터만 실무적인 것으로 바꿔보자. 아래는 사람들에 대한 데이터이다. 4명의 유저 length가 4인 데이터가 들어있고 각 user마다 family가 있고 family라는 키에는 이름과 나이가 있다. 맨 위에 코드와 완전히 똑같은 코드를 사용해서 users의 family를 뽑는다.(map을 통해서) go(users, L.map(u => u.family), L.flatten, // L.filter(a => a % 2), // L.map(a => a * a), // take(4), // reduce(add), takeAll, log); filter를 하면서 user의 나이가 20세 미만인 사람들 즉 성인이 아닌 가족들을 뽑아내고(filter를 이용해서) 해당하는 구성원의 ..

2차원 배열 다루기

아래와 같이 생긴 2차원 배열이 있다. flatten이나 기존에 작성했었던 지연적으로 동작하는 함수들을 조합하여서 2차원 배열을 다루는 코드를 작성해보자. const arr = [ [1, 2], [3, 4, 5], [6, 7, 8], [9, 10] ]; array로 부터 시작을 하고 log를 통해 출력을 하면 받은 값 그대로 나타난다. 만약 flatten을 한다면 펼쳐주게 되고 이후에 filter라는 함수를 통해 홀수만 남기는 식으로 작성할 수 있다. go(arr, flatten, filter(a => a % 2), log); // (5) [1, 3, 5, 7, 9] L.flatten이 되어도 동일한 결과를 만들 것이고 go(arr, L.flatten, filter(a => a % 2), log); //..

L.flatMap, flatMap

flatMap은 map과 flat을 동시에 하는 함수라고 생각하자. 기본적으로 최신 자바스크립트 스펙에 flatmap이 들어가는데 flatMap이 있는 이유는 자바스크립트가 기본적으로 지연적으로 동작하지 않기 때문에 그렇다. 지연적으로 동작하는 flatten이 있다면 지연적으로 동작하는 L.map을 한 후에 flatten을 할 경우에 마치 flatMap 한 번에 두 가지를 동시에 하는 flatMap과 동일하게 동작을 하게 된다. flatMap을 먼저 사용해보자. 배열안에 있는 값들을 그대로 전달을 하고 //(7) [1, 2, 3, 4, 5, 6, 7] 그리고 배열이 아닌값이 있더라고 a => a를 줬기 때문에 펼쳐진 결과가 나온다. // (10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ..

L.flatten, flatten

L.flatten이라는 함수를 만들어본다. 예를 들어 아래와 같이 값이 들어있다고 했을 때 값을 다 펼쳐서 하나의 배열로 만드는 것을 하기위해 사용하는 함수이다. 그러면서 동작을 지연적으로 하는 함수인데 구현을 해보자. L.flatten을 만들면 이터러블 프로토콜을 이용한 지연적으로 동작함수를 만들기 위해서 제너레이터로 함수를 선언한다. L.flatten = function *() { }; L.flatten은 iter값을 받아서 for of를 통해서 순회를 하고 순회를 하면서 a라는 값이 만약에 이터러블이면 계속 펼쳐서 yield하는 식으로 동작을 시켜준다. isIterable이면 어떤 일을 하고 이터러블이 아니면 값을 그대로 yield를 하는 함수를 만든다. L.flatten = function *()..

L.map L.filter로 map과 filter 만들기

이전에 map함수를 만들었었는데 아래와 같이 만들었었는데 이와 비슷한 역할을 하는 L.map이 있을 때 지연적으로 동작하지 않는 즉시 모두 값을 평가해서 결과를 만드는 map을 L.map을 통해서 만들 수가 있다. const map = curry((f, iter) => { let res = []; iter = iter[Symbol.iterator](); let cur; while (!(cur = iter.next()).done) { const a = cur.value; res.push(f(a)); } return res; }); L.map = curry(function* (f, iter) { iter = iter[Symbol.iterator](); let cur; while (!(cur = iter.ne..

take, find

L.map, L.filter take reduce 함수는 아래를 참고하자. // L.range, L.map, L.filter, take ### L.range, L.map, L.filter, take, reduce 중첩 사용 find함수는 take를 통해서 결론을 지어서 만들 수가 있다. 예를 들어서 아래와 같은 데이터가 있다고 하자. users의 나이가 있다고 하자. const users = [ { age: 32 }, { age: 31 }, { age: 30 }, { age: 29 }, { age: 28 }, { age: 27 } ]; usersd에서 첫번째로 특정조건을 만족하는 해당객체를 뽑아내는 함수가 find함수 일텐데 find함수를 간단하게 기존의 함수를 통해서 만들어 본다. find함수는 함수를..

Array.prototype.join 보다 다형성이 높은 join 함수

map filter take reduce 함수는 아래를 참고하자. ### range, map, filter, take, reduce 중첩 사용 아래의 reduce가 있는 코드의 경우에는 array에 있는 join함수를 떠올릴 수 있다. array에 있는 join함수는 array prototype에만 붙어있는 함수인데, reduce는 이터러블 객체를 다 순회하면서 축약을 할 수 있기 때문에 다양성이 높은 join함수라고 볼 수 있다. join함수를 reduce를 통해서 만들어서 아랫부분을 간결하게 하고 해당하는 함수를 재사용가능하게 해보자. join 같은 경우 sep를 받고 iter 이터러블 값을 받는다. 그리고 위에코드처럼 reduce를 하는데 받은 sep를 a와 b사이에 넣는다. const join =..

결과를 만드는 함수 reduce, take

reduce나 take는 최종적으로 어떤 함수의 결과를 만드는 함수라고 볼 수 있다. map이나 filter 같은 함수는 배열이나 이터러블한 값 즉 모나딕한 값에 안쪽에 있는 원소들에게 함수들을 합성해 놓는 역할을 한다면 reduce나 take같은 함수들은 이터러블이나 배열같이 안쪽에 있는 값들을 꺼내서 더해버리거나 (a b c d e들어있으면 a와 b를 꺼내서 더해버린다거나 하는 식으로) 배열형태의 값이나 이터레이터 형태로 있는 값을 꺼내서 깨뜨려 버려야 하기 때문에 reduce같은 함수들은 실제로 최종적으로 결과를 만드는 함수라고 볼 수 있다. 결론 map filter같은 함수는 지연성을 가질 수 있다고 볼 수 있고 reduce같은 함수들은 실제로 연산을 시작하는(연산의 시작점을 알리는) 함수라고 볼..

range, map, filter, take, reduce 중첩 사용(개발자도구로 순서확인)

지금까지 range map filter take reduce함수등을 만들고 사용해 보았고 지연적으로 동작하는 L.range L.map L.filter를 만들어 보았는데 같은문제를 즉시 평가되는 range map filter를 사용해서 해결 해보고 다른 방법으로는 L.range L.map L.filter를 사용해서 해결해보고 각각의 코드가 어떤 순서대로 평가되는지 확인해보면서 명확한 차이와 구체적인 차이가 어떻고 평가순서가 상관없는 함수형 프로그래밍에 이점등을 살펴보도록 하자. 여태까지 만들었던 함수들을 아래와 같이 나타낸다. const log = console.log; const curry = f => (a, ..._) => _.length ? f(a, ..._) : (..._) => f(a, ..._)..

L.map & L.filter

지연성을 가진 L.map을 구현해보자. 앞서 가졌던 map을 지연성을 가진 map으로 만들되, 제너레이터 이터레이터 프로토콜을 기반으로 구현해보는 L.map이 될 것이다. L.map은 평가를미루는 성질을 가지고 평가 순서를 조금 달리 조작할 수 있는 준비가 되어있는 이터레이터를 반환하는 제너레이터 함수라고 볼 수 있다. 코드를 구현해보자. 단계적으로 구현해보자. L.map은 제너레이터 함수이고 이터러블값만 받도록 한다. 그리고 내부에 있는 값을 순회를 하면서 yield를 통해서 해당하는 값을 그대로 꺼내는 것이다. 아래와 같은 map함수가 있다 했을 때 L.map을 만들고 결과를 받아서 next를 하면 아래결과가 나온다. //{value: 1, done: false} //done: false //valu..