함수형으로 전환하기
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 39 | var users = [ {id:1,name:'ID',age:36}, {id:2,name:'BJ',age:32}, {id:3,name:'JM',age:32}, {id:4,name:'PJ',age:27}, {id:5,name:'HA',age:25}, {id:6,name:'JE',age:26}, {id:7,name:'JI',age:31}, {id:8,name:'MP',age:23} ]; // 명령형 코드 // 1. 30세 이상인 users를 거른다. var temp_users = []; for (var i=0; users.length; i++){ if(users[i].age >= 30){ temp_users.push(users[i]); } } console.log(temp_users); // 2. 30세 이상인 users의 names를 수집한다. var names = []; for(var i = 0; i < temp_users.length; i++){ names.push(temp_users[i].name); } console.log(names); // 3. 30세 미만인 users를 거른다. var temp_users = []; for (var i=0;users.length;i++){ if(users[i].age < 30){ temp_users.push(users[i]); } } console.log(temp_users); // 4. 30세 미만인 users의 names를 수집한다. var names = []; for(var i = 0; i < temp_users.length;i++){ names.push(temp_users[i].name); } console.log(names); |
명령형으로 코드를 작성했을 때는 위와같이 1,2,3,4 의 문제를 해결 한다.
코드에 중복되는 부분이 많은데 그 부분을 map 과 filter를 이용하여 해결 가능하다.
filter
우선 1,3번에서 다른 부분은 조건문(if)에서 나이가 30세 이상이냐 미만이냐의 차이밖에 없다.
함수형프로그래밍에서는 그 부분을 함수로 나타내주면 된다.
1 2 3 4 5 6 7 8 9 10 | function _filter(users,predi){ var new_list = []; for(var i=0;i<users.length;i++){ if(predi(users[i])){ new_list.push(users[i]); } } return new_list; } console.log(_filter(users,function(user){return user.age >= 30;})); console.log(_filter(users,function(user){return user.age < 30;})); |
|
변경하는 방법
1단계 - _filter 라는 함수를 적용한다. 인자로는 대상이 될 배열과 필터링할 함수가 들어온다.
2단계 - 기존에 중복되던 if문에서 필터링함수를 적용한다. (필터기능을 함수에 위임)
3단계 - 결과 부분을 return 으로 받는다. 끝.
* 2단계가 인상적인데 함수형 프로그래밍에서는 추상화 단위가 함수다.
코드 설명
_filter 함수에 어떤 배열과 어떤 값을 필터링하는 함수를 넣게되면,
결과를 담을 새로운 배열 new_list를 만들고 배열의 크기만큼 반복하면서 필터함수에 값을 넘긴다.
필터함수는 조건에 맞게 true, false를 리턴하게 되고 그에 따라 조건문이 작동하여 해당 값을 새로운 배열에 푸시
*** 가장 중요한 것은 위의 _filter 함수가 단순히 users라는 배열을 위한 함수가 아니라는 것이다. ***
1 | console.log(_filter([1,2,3,4],function(num){return num%2;})) |
위 처럼 어떤 배열에서 숫자가 짝수인지 혹은 홀수인지 필터조건에 따라 사용이 가능하다.
이로써 _filter 함수는 재사용성이 좋은 함수형프로그래밍의 함수로 되었다.
따라서 위에 필터에서 이름을 좀 더 알맞게 지으려면 users 보다는 lists가 더 적절하다.
map
1 2 3 4 5 6 7 8 9 10 11 | function _map(list, mapper){ var new_list = []; for(var i = 0; i < list.length; i++){ new_list.push(mapper(list[i])); } return new_list; } var over_30 = _filter(users,function(user){return user.age >= 30;}); var names = _map(over_30,function(user){ return user.name; }) |
아까 명령형 코드의 2,4번을 map으로 해결한다.
filter를 만드는 단계와 동일하게 만들면 된다.
코드 설명
기존의 _filter 함수를 이용하여 30세 이상인 사람들로만 필터링하여 그 배열을 over_30에 담았다.
_map 함수는 over_30에서 함수로 그 사람들의 이름만을 모아 배열로 리턴한다.
- _map과 _filter에도 for문이 중복되고 있는데 그것은 each로 다음 포스트에서 해결한다.
'Javascript > 함수형 프로그래밍' 카테고리의 다른 글
커링 (curry, curryr, get) (4) | 2017.09.21 |
---|---|
함수형 프로그래밍의 장점, 다형성!(어떤 객체에만 적용가능한 메서드가 아닌 함수를 생성한다) (0) | 2017.09.20 |
each 메서드 만들어보기 (0) | 2017.08.29 |
일급 함수란? (함수를 객체처럼 다룬다, 일급 객체(first-class)) (0) | 2017.08.24 |
순수 함수란? (함수형 프로그래밍의 뿌리, 함수의 부수효과를 없앤다) (4) | 2017.08.23 |