两种函数柯里化
1. 知道函数的参数个数
/**
* @params { Function } fn 需要柯里化的函数
* @return { Function | Number }
*/
function curry(fn) {
// 利用闭包维护一个 args 数组来保存依次传进的参数
// 利用 fn.length 来控制函数的边界
let [args, l] = [[], fn.length]
// 如果传入的参数不够就返回一个接受下一个参数的函数 _
// 当传入足够的参数以后,返回函数执行结果
// note:记住在函数执行完时清空闭包内的 args,不然会影响下次调用。
return function _(prop) {
return args.push(prop) < l ? _ : fn(...args.splice(0,args.length));
}
}
function add(x, y, z){
return x+y+z;
}
let curryAdd = curry(add)
curryAdd(1)(2)(3) // 6
curryAdd(5)(5)(5) //15
2. 函数参数未知
/**
* @params { Function } fn 需要柯里化的函数
* @return { Function | Number }
*/
function curry(fn) {
// 与前者类似,不过函数边界是由 prop 来控制
// 当传入的 prop 为空时,返回函数执行结果。
// note:注意清除 args。
let args = []
return function _(...prop) {
if(prop.length){
args.push(...prop);
return _;
} else {
return fn(...args.splice(0, args.length))
}
}
}
function add(...args){
return args.reduce((sum, item)=>{
return sum + item;
}, 0)
}
let curryAdd = curry(add)
curryAdd(1)(2)(3)(5)(45)()
curryAdd(1, 2, 3)(16)()
附:
手写数组扁平化
function flat(arr){
return arr
.reduce( (list, item)
=> Array.isArray(item)
? [...list,...flat(item)]
: [...list, item] , [])
}
flat([1,2,3,[4,5,[6, [7]]]]) // [ 1, 2, 3, 4, 5, 6, 7 ]
更多函数式编程内容点此查看。