函数组合Compose
函数组合
纯函数和柯里化很容易写出洋葱代码h(g(f(x)))
-
获取数组的最后一个元素再转换成大写字母,
_.toUpper(_.first(_.reverse(array))) -
函数组合可以让我们把细粒度的函数重新组合生成一个新的函数
-
函数组合(compose):如果一个函数要经过多个函数处理才能得到最终值,这个时候可以把中间过程的函数合并成一个函数
- 函数就像是数据的管道,函数组合就是把这些管道链接起来,让数据穿过多个管道形成最终结果
- 函数组合默认是从右到左执行
//函数组合演示
function compose(f,g){
return function(value){
return f(g(value));
}
}
//反转数组
function reverse(array){
return array.reverse()
}
//获取第一个数组
function first(array){
return array[0];
}
//组合
const last=compose(first,reverse);
console.log(last([1,2,3,4]));
Lodash中的组合函数
- lodash中组合函数flow()或者flowRight(),他们都可以组合多个函数
- flow()是从左到右运行
- flowRight()是从右到左运行,使用的更多
//_.flowRight()
const _=require('lodash');
const reverse=arr=>arr.reverse();
const first=arr=>arr[0];
const toUpper=s=>s.toUpperCase();
const f=_.flowRight(toUpper,first,reverse);
console.log(f(['one','two','three']));
组合函数的实现原理
const reverse=arr=>arr.reverse();
const first=arr=>arr[0];
const toUpper=s=>s.toUpperCase();
const f=_.compose(toUpper,first,reverse);
console.log(f(['one','two','three']));
function compose(...args){
return function(value){
return args.reverse().reduce(function(acc,fn){
return fn(acc)
),value}
}
}
箭头函数
const reverse=arr=>arr.reverse();
const first=arr=>arr[0];
const toUpper=s=>s.toUpperCase();
const compose=(..args)=>value=>args.reverse().reduce((acc,fn)=>fn(acc),value);
const f=_.compose(toUpper,first,reverse);
console.log(f(['one','two','three']));
函数组合结合律
- 函数的组合要满足结合律(associativity):
- 我们既可以把g和h组合,还可以把f和g组合
//结合律(associativity)
let f=compose(f,g,h);
let associative=compose(compose(f,g),h)==compose(f,(g,h));
const _=require('lodash');
//使用lodash中提供的方法
//const f=_.flowRight(_.toUpper,_.first,_.reverse);
//const f=_.flowRight(_.toUpper,_.first),_.reverse);
const f=_.flowRight_.toUpper,(_.first,_.reverse);
console.log(f(['one','two','three']));
如何调试
//NEVER SAY-->never-say
const _=require('lodash');
//调试
//const log=v=>{
// console.log(v)
// return v
//}
//优化调试
const trace=_.curry((tag,v)=>{
console.log(tag,v);
return v;
});
//_.split()
const split=_.curry((sep,str)=>_.split(str,sep));
//.toLower()
//_.join()
const join=_.curry((sep,array)=>_.join(array,sep));
//const f=_.flowRight(join("-"),log,_.toLower, split(''));
//_.map();
const map=_.curry((fn,array)=>_.map(array,fn));
const f=_.flowRight(join("-"),trace('map之后打印'),map(_.toLower), split(''));
console.log(f("NEVER SAY"));

浙公网安备 33010602011771号