函数组合是函数式编程中很是重要的思想,它的实现的思路也没有特别复杂。有两种函数组合的方式,一种是pipe
,另外一种是compose
。前者从左向右组合函数,后者方向相反。
下面就是一个最简单的能够组合两个函数的composejavascript
let compose = (f, g) => (...args) => f(g(...args));
在实际应用中,只能组合两个函数的组合函数显然不能知足要求,咱们须要能够组合任意个函数的组合函数。下面提供两种思路。java
两种方法一种是递归,一种是循环,其实都是同样的。具体的思路就是,先写一个组合能够两个函数的compose2,用compose2先把传进来的末尾的两个函数组合了,返回一个函数func,而后再compose2把func和传进来的下一个函数组合起来,以此类推。git
循环的方法github
let compose2 = (f, g) => (...args) => f(g(...args)); let compose = (...funcArgs) => (...args) => { let funced = funcArgs[funcArgs.length - 1]; for (let i = funcArgs.length - 2; i >= 0; i--) { if (i === 0) { return compose2(funcArgs[i], funced)(...args); } funced = compose2(funcArgs[i], funced); } } // 与compose组合方向相反的函数组合函数 let pipe = (...funcArgs) => compose(...funcArgs.reverse());
递归的方法编程
let compose2 = (f, g) => (...args) => f(g(...args)); let compose = (...funcArgs) => (...args) => { let [...funcArgsCopy] = funcArgs; let callSelf = func => { if (funcArgsCopy.length === 0) return func; let funced = compose2(funcArgsCopy.pop(), func); return callSelf(funced); } return callSelf(funcArgsCopy.pop())(...args); } let pipe = (...funcArgs) => compose(...funcArgs.reverse());
上面的思路仍是有点麻烦,其实不用纠结在组合,直接把前一个函数的处理参数以后的返回值传给下一个函数就能够了。
循环的方法数组
let compose = (...funcArgs) => (...args) => { for (let i = funcArgs.length - 1; i >= 0; i--) { args = i === funcArgs.length - 1 ? funcArgs[i](...args) : funcArgs[i](args); } return args; } let pipe = (...funcArgs) => compose(...funcArgs.reverse());
递归的方法函数式编程
let compose = (...funcArgs) => (...args) => { let [...funcArgsCopy] = funcArgs; let funced = (...func) => { if (funcArgsCopy.length === 0) return func[0]; func = funcArgsCopy.pop()(...func); return funced(func); } return funced(...args); } let pipe = (...funcArgs) => compose(...funcArgs.reverse());
我在github https://github.com/zhuanyongx...函数