• 函数式编程 -- 函数组合 -- 管道


    什么是函数组合?

    把细粒度的函数组合成一个新的函数

    组合函数有什么用?

    假设有一个数组,我们要先翻转数组,再获取数组中的第一个元素,然后把这个元素转化成大写字母

    var arr=["a","b","c"]
    var upperChar = toUpper(getFirstChar(reverseArray(arr)))
    

    可能我们的代码写完后是上面这样的,就像洋葱一样,一层一层的,当我们需要增加或者 减少逻辑时,修改代码稍显麻烦,其实我们可以把这些函数组合起来,这样修改业务逻辑时,只需要修改传入组合函数的参数就行了

    函数组合

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

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

      // 函数组合演示,获取数组最后一个元素
      // 组合函数
      function compose(f,g){
        return  function(value){
          retturn f(g(value))
        }
      }
      // 数组翻转函数
      function reverse(array){
        retutrn  array.reverse()
      }
      // 获取数组第一个元素
      function first(array){
        return array[0]
      }
      // last是组合后的函数,集合了reverse方法和first方法,作用是取得数组的最后一个元素
      const  last=compose(first,reverse)
      console.log(last([1,2,3,4]))
      
      
    • 这里只是讲的函数组合与管道的思想,目的就是想说函数可以任意的组合和调用,函数式编程可以让函数最大程度的被重用

    lodash中的函数组合

    // lodash 中的函数组合方法:_.flowRight(),此方法可以接收任意多个需要组合的函数作为参数
    const _ = require('lodash')
    // 用于组合的reverse方法,作用是翻转数组
    const reverse =  arr =>arr.reverse()
    // 用于组合的first方法,作用是取数组的第一个元素
    const first = arr => arr[0]
    // 用于组合的toUpper方法,作用是把字符串转换成大写
    const toUpper = s = >s.toUpperCase()
    // 组合函数flowRight的执行是从右向左
    // 先执行reverse将数组翻转
    // 再执first取数组的第一个元素
    // 最后执行toUpper将取得的元素转换成大写
    const f = _.flowRight(toUpper,first,reverse)
    console.log(f(['one','two','three']))
    

    模拟一下lodash的flowRight方法

    function myFlowRight(...args){
      return function(value){
        return args.reverse().reduce(function(acc,fn){
          return fn(acc)
        },value)
      }
    }
    
    //上面myFlowRight用箭头函数重写如下:
    const myFlowRight=(...args)=>value=>args.reverse().reduce((acc,fn)=>fn(acc),value)
    
    // 测试一下
    const reverse =  arr =>arr.reverse()
    const first = arr => arr[0]
    const toUpper = s = >s.toUpperCase()
    
    const f = myFlowRight(toUpper,first,reverse)
    console.log(f(['one','two','three']))
    

    函数组合的结合律

    因为函数组合后返回的还是一个函数,所以函数组合是满足结合律的
    像下面一样,可以把f、g组合,也可以把g、h组合,结果都是一样的

    // 结合律
    let f = compose(f,g,h)
    let associative = compose(compose(f,g),h) == compose(f,compose(g,h)) 
    

    管道

    • 下面这张图表示程序中使用函数处理数据的过程,给fn函数输入参数a,返回结果b,中间的处理过程我们称之为数据处理管道

    • 当fn比较复杂时,我们可以把函数fn拆分成多个小函数,此时多了两个运算过程中产生的m、n

    • 下面这张图中可以想象成把fn这个管理折成了3个管道f1,f2,f3,数据a通过管道f3得到结果m,m再通过f2得到n,n最后通过f1得到b

    用代码表示如下:

    var fn = compose(f1,f2,f3)
    b=fn(a)
    
  • 相关阅读:
    php js表单登陆验证
    jQuery Ajax 简单的实现跨域请求
    常见http代码错误原因及处理
    使用git做服务器端代码的部署
    mysql之消息队列
    MySQL触发器使用详解
    mysql之触发器before和after的区别
    mysql之触发器trigger
    手把手教你使用Git
    xcode: {} 花括号缩进一个空格
  • 原文地址:https://www.cnblogs.com/MissSage/p/14878903.html
Copyright © 2020-2023  润新知