Web Front-end/함수형 프로그래밍(FP)

[JS/함수형] Map,Filter 구현

Iterable Protocol을 따르는 값들은, Map,Filter,Reduce와 함께 쓰면 아주 실용적으로 쓸 수 있게 됩니다. 
(순회를 간단하고, 직관적으로 할 수 있고, 필요한 값들을 뽑아 낼 수 있습니다)


Map


Map은 JSON과 같은 "데이터 파일"이 입력이 들어올 때,하나의 함수로 내가 원하는 값을 뽑아낼 수 있도록,하는 장점이 있습니다. 예시를 보면서, Map에 대한 느낌을 받아보시죠!

 

  • 아래와 같은 학생정보가 있다고 합시다
const students=[
  {name:"Kim",major:"ComputerScience"},
  {name:"Lee",major:"Business"},
  {name:"Jay",major:"Music"},
  {name:"Dode",major:"Rap"},
  {name:"Yoon",major:"Cooking"},
]
  • 위의 학생 정보에서, 우리가 Map을 모르는 상태에서, name과 major의 정보를 알고싶다면, 아래와 같은 코드를 떠올릴 수 있겠습니다.
const students=[
  {name:"Kim",major:"ComputerScience"},
  {name:"Lee",major:"Business"},
  {name:"Jay",major:"Music"},
  {name:"Dode",major:"Rap"},
  {name:"Yoon",major:"Cooking"},
]

//for of문을 사용해보기
let names=[];
for (const n of students){
  names.push(n.name);
}
//내가 전공을 알고싶다면?
let majors=[]
for (const n of students){
	majors.push(n.major);
}

 

위의 코드를, map을 이용하면서, "함수형"답게 짜보겠습니다.

  • 함수형에서는 순수함수를 지향하고 있습니다. 따라서, 인자값(Parameter)을 처리해서, return값을 줍니다.
  • map에서 iter(이터러블)을 받게되면, 이터러블 안에 속성(이름,전공과 같은)이 어떤것이 있는지 모르기 때문에, 어떤 속성이 있는지 받아줄 function이 필요하게 됩니다.
  • 이 속성은, 사용자가 정의해야 하기 때문에, function으로 Parameter을 받게됩니다.
//map(탐색할것,탐색할 자료)

const map = (f,iter) =>{
	res=[]
    for (const a of iter){
    	res.push(f(a))
    }
    return res
}
//내가 만약, name을 알고싶다면?
console.log(map(s=>s.name,students));

//내가 만약, major을 알고싶다면?
console.log(map(a=>a.major,students));

위와 같이, map은 iterable이면, 동작할 수 있도록 만들어놓으면

  1. Generator로 생성한 모든 값들을 순회할 수 있게 되고,
  2. 결국, 거의 모든 값들을 순회할 수 있게 만들어지게 됩니다.

 

응용!

저번에 만들어놓은 짝수Iterable을 통해서, N까지 짝수를 나열하는 코드를 짜보겠습니다!

See the Pen JS_Example_Map by Doge (@DogeIsFree) on CodePen.

 

 

활용

 

Map은 JS에서 Array,String,Map 등, Iterator로 구현되어 있는 자료형에서 사용할 수 있는 메소드이고, 동작원리는 위에서 예제들을 짜면서 ,충분히 이해가 됬을거다!

다른점이라면, array안에서는 메서드 형태로 구현이 되어있기 때문에, this도 쓰였을거고, 외부 배열을 받는 형태로 구현이 되어있지 않을거라는 점이다!

OneToFive=[1,2,3,4,5]
/*
Map Format
arr.map(callback(currentValue[, index[, array]])[, thisArg])
*/

total=OneToFive.map((value)=>{
	return value+1;
})//20

res=total.map((value)=>{
	if (value%2===0){
    	return "짝수";
    }
    else{
    	return "홀수";
    }
})

 

Filter

 

원하는 값을 조건에 맞게, Filtering하고 싶다면, 어떻게 해야할까?

우리가 쇼핑을 한다고 했을 때

  • 자본의 사정에 따라서 2만원 이하의 상품만 보고싶거나
  • 품질을 생각해서, 난 2만원 이상의 상품만 보고싶다고 생각할 수 있을것이다.

아래와 같은 상품목록이 있다고하자.

const products = [
  {name:"반팔티",price:15000},
  {name:"긴팔티",price:20000},
  {name:"후드티",price:30000},
  {name:"바지",price:25000},
  {name:"반바지",price:20000},
]

 

Map에서 했던것 처럼, 바로 함수형으로 구현하면 아래와 같이 될 것이다 :)

const filter = (f,iter) =>{
  let res=[];
  for (const a of iter){
    if (f(a)) res.push(a);
  }
  return res;
}


console.log(...filter(p=>p.price>=20000,products));

 

활용

 

JS에서 Filter 또한 구현되어 있다.

/*
arr.filter(callback(element[, index[, array]])[, thisArg])
*/

const words=["hello","limit","title","aa","bb","cc"]

const res=words.filter(word=>word.length<3);

console.log(res);
//[aa,bb,cc]

 

Ref

 

이 글은 유인동님의 함수형 프로그래밍과 JS ES6강의를 보고 나름대로 정리해서, 작성한 글 입니다. :)

https://www.inflearn.com/course/functional-es6/dashboard

 

함수형 프로그래밍과 JavaScript ES6+ - 인프런 | 강의

ES6+와 함수형 프로그래밍을 배울 수 있는 강의입니다. 이 강좌에서는 ES6+의 이터러블/이터레이터/제너레이터 프로토콜을 상세히 다루고 응용합니다. 이터러블을 기반으로한 함수형 프로그래밍,

www.inflearn.com