• JS函数组合


    如果一个功能需要多个细粒度的函数进行组合实现,我们和很容易写出洋葱代码:h(g(f(x)))
    例如:获取数组的最后一个元素再转换成大写字母,_.upperCase(_.last(arr))
    请添加图片描述
    函数组合可以让我们写出这样嵌套的代码

    函数组合可以看成城市地下管道

    下面这张图表示程序中使用函数处理数据的过程,给 fn 函数输入参数 a,返回结果 b。可以想想 a 数据通过一个管道得到了 b 数据。当 fn 函数比较复杂的时候,我们可以把函数 fn 拆分成多个小函数,此时多了中间运算过程产生的 m 和 n。请添加图片描述
    下面这张图中可以想象成把 fn 这个管道拆分成了3个管道 f1, f2, f3,数据 a 通过管道 f3 得到结果 m,m再通过管道 f2 得到结果 n,n 通过管道 f1 得到最终结果 b
    请添加图片描述
    伪代码

    fn = compose(f1, f2, f3)
    b = fn(a)
    
    • 1
    • 2

    函数组合

    如果一个函数要经过多个函数处理才能得到最终值,这个时候可以把中间
    过程的函数合并成一个函数

    • 函数就像是数据的管道,函数组合就是把这些管道连接起来,让数据穿过多个管道形成最终结果
    • 函数组合默认是从右到左执行

    lodash 的函数组合

    我们使用lodash 函数组合方法,将数组最后一个元素大写

    var _ = require('lodash');
    
    let arr = ["hcj", 'wcj'];
    let compose = _.flowRight(_.upperCase ,_.last);
    console.log(compose(arr));
    
    • 1
    • 2
    • 3
    • 4
    • 5

    函数组合原理

    1. 接收不固定数量的函数形参,返回一个函数,接受一个参数
    2. 反转函数形参,依次调用,返回结果
    let arr = ["hcj", 'wcj'];
    function compose(...args) {
        return function(value) {
          return args.reverse().reduce(function(total, fn){
                return fn(total);
            }, value);
        }
    }
    
    let composeFn = compose(_.upperCase ,_.last);
    console.log(composeFn(arr));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    结合律

    和数学一样,函数组合也支持结合律

    // 结合律(associativity)  ture
    let associative = compose(compose(f, g), h) == compose(f, compose(g, h))
    
    • 1
    • 2

    调试

    在我们使用组合时,如果结果和我们预期不一致,我们如何进行调试?以下面例子来说明:

    // NEVER SAY DIE --->   never-say-die
    var _ = require('lodash');
    
    let str = "NEVER SAY DIE"
    let split = _.curry((sep, str) => _.split(str, sep));
    let map = _.curry((fn, arr) => _.map(arr,fn));
    let join = _.curry((sep, arr) => _.join(arr, sep));
    
    // debug 函数
    let trace = _.curry((flag, data) => {
        console.log(flag,data)
        return data;
    });
    
    let compose = _.flowRight(trace("join") ,join("-"),trace("map") ,map(_.lowerCase) ,trace("split") ,split(" "));
    console.log(compose(str));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    【Java】Collections.shuffle 洗牌方法,随机重排序一组元素
    权威认可!安全狗获CNVD“漏洞信息报送贡献单位”殊荣
    网络安全——基于联合查询的字符型GET注入
    java-php-python-汽车售后服务信息管理系统的设计与实现计算机毕业设计
    好的架构是进化来的,不是设计来的
    C++11 ——— 右值引用和移动语义
    【Pytorch Lighting】第 6 章:深度生成模型
    Python项目维护不了?可能是测试没到位。Django的单元测试和集成测试初探
    算法44-异或运算|交换int|找出出现奇数次的数|提取右边以一个1
    多核调度算法 - 加速因子 - 本质理解
  • 原文地址:https://blog.csdn.net/sanfeng_hu/article/details/127457713