본문 바로가기

Study/VanillaJS

[개념잡기] 함수형 프로그래밍 - (2) map, filter

[개념잡기] 함수형 프로그래밍 - (2) map, filter

서론

명령형 코드를 함수형 프로그래밍 코드로 변형하는 작업을 해볼 것이다.

명령형 코드

우선 기본이 되는 users 객체 배열이다.

var users = [
  {id: 1, name: 'ID', age: 29},
  {id: 2, name: 'QW', age: 30},
  {id: 3, name: 'WE', age: 31},
  {id: 4, name: 'ER', age: 32},
  {id: 5, name: 'RT', age: 21},
  {id: 6, name: 'DF', age: 28},
  {id: 7, name: 'AS', age: 35},
  {id: 8, name: 'IS', age: 25}
]

명령어 코드로 다음과 같은 데이터를 뽑아내보자.

  • 30세 이상인 users를 거른다
  • 30세 이상인 users의 name 수집
  • 30세 미만인 users를 거른다
  • 30세 미만인 users의 age 수집
// 30세 이상인 users를 거른다
var temp_users = []
for (var i = 0; i < users.length; i++) {
  if(users[i].age >= 30) {
    temp_users.push(users[i])
  }
}
console.log(temp_users)
// 30세 이상인 users의 name 수집

var names = [];
for (var i = 0; i < temp_users.length; i++) {
  names.push(temp_users[i].name)
}
console.log(names)
// 30세 미만인 users를 거른다

var temp_users = []
for (var i = 0; i < users.length; i++) {
  if(users[i].age < 30) {
    temp_users.push(users[i])
  }
}
console.log(temp_users)
// 30세 미만인 users의 age 수집

var ages = [];
for (var i = 0; i < temp_users.length; i++) {
  ages.push(temp_users[i].age)
}
console.log(ages)

함수형 프로그래밍

위에 코드들은 공통적인 것들이 있다. 그 부분을 filter, map 이라는 함수를 묶어서 모듈화해보겠다.

filter

filter 함수는 첫번째 인자로 리스트를 받고, 두번째로 조건을 수행하는 함수를 받고 그 조건으로 걸러진 새로운 리스트를 반환한다.

_filter([리스트], [함수]) // 새로운 리스트
function _filter(list, predi) {
    var new_list = []
    for(var i = 0; i < list.length; i++) {
        if(predi(list[i])) {
            new_list.push(list[i])
        }
    }
    return new_list
}

filter 함수를 이용해 조건인 30세 이상인 users를 거르는 코드를 작성해 보겠다.

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

map

map 함수는 어떤 객체의 특정 키를 배열 형태로 돌려준다. 첫번째 인자로 리스트를 받고, 두번째 인자로 함수를 받는다.

_map([리스트], [함수]) // 새로운 리스트
function _map(list, mapper){
    var new_list = []
    for(var i = 0; i < list.length; i++) {
        new_list.push(mapper(list[i]))
    }
    return new_list
}

map 함수를 이용해 users의 name 수집해보겠다.

var names = _map(users, function(user){ return user.name })
console.log(names)

위에 조건에 맞게 코딩

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

var names = _map(over_30, function(user){ return user.name })
console.log(names)

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

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

활용

30세 이상의 이름만을 가져오는 코드는 filter 함수의 반환값은 리스트이기 때문에 다음과 같이 가능하다.

console.log(
    _map(
        _filter(user, function(user){ return user.age >= 30 }),
        function(user) { return user.name }
    )
)