고차함수 부분을 복습하다가 여러 개의 함수를 파이핑하는 코드를 작성하는 연습을 다시 해보기로 했다.
const mixed = [[1,2,3,4],5,6,'e','fg',[7,8,9],10,'book'];
function make1DepthArr(arr){
return arr.reduce((acc,cur) => acc.concat(cur),[]);
}
function getNumber(arr){
return arr.filter(el => typeof el === "number");
}
function sum(arr){
return arr.reduce((acc,cur) => acc + cur , 0);
}
function compose(...arg){
let composedFunc = arg[0];
for(let i = 1 ; i < arg.length ; i++){
composedFunc = arg[i](composedFunc);
}
return composedFunc;
}
이렇게 작성을 하고, 함수를 호출하였더니 arr.filter는 함수가 아니다 라는 에러메세지가 떴다.
filter함수 자체에서는 문제가 없었기 때문에, 다음과 같이 콘솔로그를 찍어 각각의 함수들이 문제가 없는지를 확인해보았다.
console.log(make1DepthArr(mixed));
console.log(getNumber(make1DepthArr(mixed)));
console.log(sum(getNumber(make1DepthArr(mixed))));
세 코드 모두 이상 없이 정상적인 결과를 출력하고 있었다.
그러면 위 코드 중에서 compose function 작성에서 문제가 있었던 것이라고 결론을 내릴 수 있다.
먼저, 반복문의 각 단계에서 어떤 결과가 출력되는지를 풀어 써 보았더니 ,다음과 같았다.
//i === 1일때
composedFunc === getNumber(make1DepthArr())
//i === 2일때
composedFunc === sum(getNumber(make1DepthArr()))
써 놓고 보니 문제점이 무엇인지를 알 수 있었다. 함수는 잘 합성이 되고 있지만, 함수에 parameter가 없었다.
이렇게 작성을 하게 되면, 함수에 무슨 argument를 전달하건 간에 argument가 함수의 영향을 받지 못하기 때문에, 위와 같은 오류가 발생하는 것이라고 생각해 볼 수 있겠다.
이를 해결하려면, parameter를 적어주어야 하므로 다음과 같이 고쳐 쓸 수 있을 것이다.
function compose(...arg){
return function(data){
let composedFunc = data;
for(let i = 0 ; i < arg.length ; i++){
composedFunc = arg[i](composedFunc)
}
return composedFunc;
}
}
내부의 반복문은 다음과 같이 reduce 함수로도 표현을 할 수 있겠다.
function compose(...arg){
return function(data){
return arg.reduce((acc,cur)=>cur(acc),data);
}
}
이 함수는 여러 함수들을 합성해주는 함수이기 때문에, 유지보수면에서 자주 쓸 수 있을 함수라고 생각한다. 오래오래 기억해두자.