함수형으로 전환하기(_filter, _map)- part 2

이번에는 아래와같은 문제를 명령형 프로그래밍코드로 해결한 뒤 , 함수형 프로그래밍으로 refactoring 하도록 하겠습니다.

1
2
3
4
5
6
7
8
9
10
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}
];

users라는 배열이 존재합니다. json표기법을 따르고 있네요..ㅎㅎ

이 배열은 id, name, age를 가지는 8개의 객체를 포함합니다.

위의 배열로 4가지 문제를 해결해 봅시다.

  1. 나이가 30세 이상인 user를 거른다.
  2. 걸러진 user들의 name을 수집한다.
  3. 나이가 30세 미만인 user를 거른다.
  4. 걸러진 user들의 age를 수집한다.


    1. 나이가 30세 이상인 user를 거른다.
    1
    2
    3
    4
    5
    6
    7
     var user_over30 =[];
    for(var i=0; i< users.length; i++){
    if(users[i].age >= 30){
    user_over30.push(users[i]);
    }
    }
    console.log(user_over30);

user_over30이라는 빈 배열을 생성하고,

for문으로 users배열 객체하나하나의 나이를 체크하여

30이 넘는 객체를 배열 user_over30 에 담아 콘솔창으로 확인합니다.

결과값

30세 이상인 user만 제대로 걸러냈습니다.


  1. 걸러진 user들의 name을 수집한다.

    1
    2
    3
    4
    5
    var names = [];
    for(var i =0 ; i< user_over30.length ; i++){
    names.push(user_over30[i].name);
    }
    console.log(names);

이번에는 30세 이상인 user들의 name이 담길 names라는 배열을 새롭게 생성합니다.

그리고 for문을 돌려 i번째 user_over30의 이름을 하나씩 배열에 담습니다.

결과값

30세 이상인 user이 name을 수집했습니다.


  1. 나이가 30세 미만인 user를 거른다.
  2. 걸러진 user들의 age를 수집한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//3. 30세 미만인 users를 거른다.
var users_under30 = [];
for(var i=0; i <users.length; i++){
if(users[i].age < 30){
users_under30.push(users[i]);
}
}
console.log(users_under30 );

//4. 30세 미만인 users의 ages를 수집한다.
var ages = [];
for(var i =0; i < users_under30.length; i++){
ages.push(users_under30[i].age)
}
console.log(ages);

이번은 위의 1번 2번에서 나이 조건을 30세 미만으로 바꾸기만 하면 됩니다.

결과값

30세 미만인 user와 그들의 age를 제대로 가져왔습니다.


.
.
.

지금까지는 명령형 코드로 프로그래밍했습니다.

이제 함수형으로 전환하여 중복코드를 제거하고

좀 더 다형적이며 활용성 높은 코드로 바꿔보도록 합시다!!!

.
.
.
먼저 30세이상인 코드와 미만인 코드의 중복을 줄이고 싶네요.. 함수형프로그래밍에서 쉽게 줄일수있습니다^^

이 문제는 filter라는 함수를 통해 가능하답니다.

_filter 로 리펙토링!!

filter라는 순수함수를 새롭게 생성하고 그냥 외부에서 변수를 받아와 필요한 시점에서만 사용되도록 만드는 것…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function _filter(list, predi){ //여러번 사용할것을 감안해 users--> list로 바꾸는것이좋음.
var new_list = []; // 위처럼 여러번 사용될 것이기 때문에 user_over30, user_under30 --> new_list로 바꾸는게 좋아요..

for(var i=0; i < users.length; i++){
if(predi(users[i])) { //predi는 i번째 users라는 인자값을 받아 user.age >= 30 라는
new_list.push(users[i]);
}
}
return new_list;
}

var over_30 = _filter(users, function(user){return user.age >= 30;});
console.log(over_30);

var under_30 = _filter(users, function(user){return user.age < 30 ;});
console.log(under_30);

_filter라는 함수는 list, predi라는 인자를 받습니다.
list, 즉 array 타입으로된 어떤 배열이 와도 됩니다. predi는 함수이고,
어떠한 판별 조건을 리턴해주는 역할을 합니다.

이번에는 30세 이상, 또는 30세 미만이면~ 이라는 조건을 return하여 조건에 맞는 user들을
over_30과 under_30이라는 객체에 담았습니다.

결과값


_map 으로 리펙토링!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

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 names = _map(over_30, function(user){
return user.name;
});

var ages = _map(under_30, function(user){
return user.age;
});

console.log(names);
console.log(ages);

우선 _map이라는 함수를 차근차근 살펴봅시다.
_map함수는 인자로 list와 mapper를 가지고 list는 _filter의 list인자와 같이 배열이라는 조건만 만족한다면
어떠한 배열이 와도 상관없습니다.
mapper 인자는 함수형태이고, i번째 list를 인자로 보내서 i번째 list의 name, 또는 age를 return합니다.
그런 다음, 새롭게 생성되었던 new_list 객체안에 조건을 만족하는 list의 name또는 age가 담기게 됩니다.
최종적으로, 그 new_list를 리턴하면서 이 함수의 역할은 끝나게 됩니다.

우리는 위에서 걸러진 list인 over_30과 under_30을 list인자로 보내야 합니다.
그리고 mapper인자로 조건에 만족하는 list의 name을 리턴하는 것을 보내서 names라는 객체에 담아 콘솔로 확인합니다.
(age의 경우도 같습니다.)

결과값

_filter함수는 그 자체로 함수이기때문에 위처럼 꼭 user들을 거르는것이외에도 다른 작업에서 사용될 수 있습니다.

이 함수를 사용하기위해선 인자값의 형태를 배열값으로 지켜주면서, predi부분은 순수함수를 만족하는 인자를 넘겨주면 됩니다.

.
.
.

다음 포스팅에서는 each함수를 통해서 for문 중복을 제거해보도록 하겠습니다.

Share