본문 바로가기
웹 개발/javascript

filter, map을 이용한 코드를 reduce로 refactoring하기

by 스토리라이언 2021. 2. 22.

다음과 같은 문제가 주어졌다고 생각해 보자.

let arr = [1,2,3,4,5];
function filter() {
  const filterMapped = arr.filter(x => x % 2 !== 0).map(x => x*2);
  return filterMapped;
}
filter();// [2, 6, 10]

filter함수는 filter와 map을 사용해서 주어진 arr에 홀수 중인 것에 2를 곱한 값을 리턴한다. 

이것을 구현하기 전에 먼저 arrow function(화살표 함수)가 익숙하지 않아서 mdn 등 문서를 통해 화살표 함수의 기능을 익히는 시간을 가졌다. 화살표 함수는 익명 함수로 function 표현을 사용하지 않으니 구문이 짧아져 많이 편했다. 계속 화살표 함수를 사용해 봐야 겠다. 

 

그렇다면 reduce을 한 번 사용해서 같은 기능을 구현해 보자. 어떻게 하면 좋을까?

 

/*
filter를 통해서 [1,3,5]를
map를 통해서 [2,6,10]라는 값을 가져왔다. 
reduce를 사용해서 두 가지를 한꺼번에 구현해 보자. 
*/
function reduceFun() {
let arr=[1,2,3,4,5];
 return arr.reduce(function (acc, cur){
 //if문 안의 조건은 arr 배열 가운데 cur의 짝수가 있으면 참이다. 
 //acc.push(cur)은 초기값이 []이니 [1,3,5]가 담긴다. 
      if(arr.includes( cur % 2)) acc.push(cur);//acc에 [1,3,5]가 담겼다.
      return acc;
      //배열.map을 통해 2를 곱한 수를 리턴한다.
    },[]).map(x => x*2); //[2,6,10] 값이 리턴
}

map를 사용하지 않고 어떻게 해서든지 2를 곱해서 [2,6,10]이 나오게 하려고 다음과 같은 시도를 했다. * 2를 두 군데 붙여보았는데 에러가 뜬다. 

function reduceFun() {
let arr=[1,2,3,4,5];
 return arr.reduce(function (acc, cur){
      if(arr.includes( cur % 2)) acc.push(cur);//acc에 [1,3,5]가 담겼다.
      return acc;
    },[])*2;
}
reduceFun(); //NaN 

function reduceFun() {
let arr=[1,2,3,4,5];
 return arr.reduce(function (acc, cur){
      if(arr.includes( cur % 2)) acc.push(cur);//acc에 [1,3,5]가 담겼다.
      return acc*2;
    },[]);
}
reduceFun();// VM3336:4 Uncaught TypeError: acc.push is not a function

2시간 넘게 이것 저것 시도하고 mdn 문서 등을 보는데 쉽게 풀지 못했다. 

계속 삽질하고 고민해 본 결과 문제는 결국 acc에 어떤 값이 들어가는가이다. 

내가 지금껏 한 방식은 acc.push(cur)이다. 그러니 acc에 [1,3,5]가 들어간다. 

그렇다면 곱하기 2의 값이 들어가게 하려면 어떻게 해야 할까?

function reduceFun() {
let arr=[1,2,3,4,5];
 return arr.reduce(function (acc, cur){
      //acc.push(cur)하면 acc에 [1,3,5] 홀수가 담긴다. 그렇다면 acc에 [2,6,10]이 담기게 하려면
      //어떻게 해야 할까? acc.push(cur*2)를 하면 곱하기 2의 배열이 새롭게 할당된다. 
      if(arr.includes( cur % 2)) acc.push(cur*2);//acc에 [2,6,10]이 담긴다. 
      return acc;
    },[])
}

댓글