map()과 filter()를 만들어보자

이경준·2020년 11월 21일
0

1.map()

map()은 배열을 순회하는 반복문이다. 물론 일반적인 for나while같은 반복문과는 다르다.
배열안에서 하나하나 산복문을 돌면서 어떻게 할 것인지를 정의하면 배열의 값 하나하나에 적용되고, 그 값을 다시 새로운 배열로 반환한다.
중요한것은 새로 만들어진 배열은 실행하는 배열과는 다른 배열이다.
사용방법은 배열.map(function(요소,인덱스,배열){}) 이다.


연습1) 배열에 2를 곱하는 반복문을 만들자.

const arr = [1,2,3,4,5];
const arrFromMap = arr.map(function(n){
  return n*2
})

console.log(arrFromMap)
//[2,4,6,8,10]

map을 이용하여 콜백함수의 인자를 n으로 지정하고 곱하기2를 반환하도록 하였다.
map이 arr의 값을 하나하나 순회하며 2씩 곱한 값을 새로운 배열에 반환하였다. 처음엔 forEach와 똑같다고 생각했는데 arrFromMap이라는 변수명을 선언하여야 쓸수 있다는 특징을 가지고 있다.


연습2) 3보다 작다면 2씩곱하고 크다면 그냥 반환하자.

const arr = [1,2,3,4,5];
const arrFromMap2 = arr.map(function(n){
  if(n<3){
    return n*2;
  }
  return n;
});

console.log(arrFromMap2)
//[2,4,3,4,5]

arr값중 3보다 작은 1,2는 2씩 곱하여 2,4를 반환하였고 나머지는 조건문에 맞지 않기에 그냥 반환되도록 하였다.
처음엔 if조건문안에 return을 하지않으면 [1,2,3,4,5]로 그대로 반환되니 주의하여야한다.


연습3) map()을 만들어보자

const arr = [1,2,3,4,5];
Array.prototype.map = null
//이제 map은 작동하지 않는다.

Array.prototype.newMap = function(func){
  const isMap = [];
  this.forEach(function(n){
    isMap.push(func(n));
  });
  return isMap
};

const isArray = arr.newMap(n=>n*3)
console.log(isArray)
//[3,6,9,12,15]

map과 같이 배열을 하나하나 순회하는 forEach를 써서 완성하였다.
일단 빈배열을 만들어서 최족적으로 반환하는 방식으로 시작하였고, forEach문 안에서 하나씩 돌면서 push하면 완성 될것이라고 생각했다. 그러나 newMap이 어떻게 arr을 순회할것인지가 어려웠다.

newMap이 호출시 배열.newMap() 방식으로 호출될 것이기에 this가 배열이 될것이라고 생각했으며, this.forEach()를 쓰니 배열을 하나하나 순회하였다. 그리고 newMap안에는 콜백함수로 받아야하기에 func(n)으로 push하여 완성하였다.


2.filter()

filter()는 map()과 같이 배열을 순회하는 반복문이다. 그러나 콜백함수안에 정의하는 조건에 값에 true인 것만 반환하여 새로운 배열을 만들어낸다.

연습1) 40보다 작은수를 뽑아내자

const arr = [10,20,30,40,50,60];

const arrFromFilter = arr.filter(function(n){
  return n < 40;
});

console.log(arrFromFilter)
//[10,20,30]

filter()의 콜백함수 안에 n<40이라는 조건만 정의 하였다.
결과를 보면 알다시피 조건의 값이 true인것만 뽑아낸것을 볼 수 있다.


연습2) 가격이 5000원이상만 뽑아내자

const village = [
  {type:'apartment', price:3000},
  {type:'roofTop', price:5000},
  {type:'apartment', price:7000},
  {type:'villa', price:1000},
];

const filterdVillage = village.filter(function(n){
  return n.price >= 5000
})

console.log(filterdVillage)
//[{type:'roofTop', price:5000},{type:'apartment', price:7000}]

filter()를 사용하여 5000원이상인 오브젝트만 새로운 배열에 담았다.
처음에는 if문이 들어가야하는 혼돈을 했지만 filter가 조건의 true값만 뽑아낸다는 성격을 생각해보니 그럴 필요가 없었다.


filter()를 만들어보자.

const arr = [10,20,30,40,50,60];
Array.prototype.filter = null;
//이제 filter는 작동하지 않는다.

Array.prototype.newFilter = function(func){
  const isFiltered = [];
  this.forEach(function(n){
    if(func(n)){
      isFiltered.push(n)     
    }
  })
  return isFiltered;
}

const isArr = arr.newFilter(n=>n<40);
console.log(isArr)
//[10,20,30]

map을 만들었던 방식대로 this에 forEach를 사용하여 새로운 배열을 반환하는 방식이다. 그러나 그대로 사용하면 결과가
[true,false]방식으로 배열에 push하게 될것이다.
또한 true일때만 값을 넣어야한다는 조건문도 달아야 했다.
if문을 사용하여 func(n)이 true일때 빈배열에 n값만 push할 수 있도록 하였다.

결론

용어 개념이 부족하여 횡설수설하는 것 같으니 용어 공부를 좀 더 해야겠다...

profile
내가 기억하기위한 블로그

0개의 댓글