zoukankan      html  css  js  c++  java
  • 函数式编程 -- 函数组合 -- 管道

    什么是函数组合?

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

    组合函数有什么用?

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

    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)
    
  • 相关阅读:
    Java Logger 使用总结
    java中用Eclipse打JAR包,包含外部JAR
    安装e(fx)clipse到Eclipse (JavaFX工具)
    肾亏怎么办 下面给你支支招
    汇编cmp比较指令详解
    eclipse安装插件报错Unable to read repository at
    Eclipse将引用了第三方jar包的Java项目打包成jar文件的两种方法
    Java开发桌面程序学习(二)————fxml布局与控件学习
    JavaFX入门(二):JavaFX和FXML
    Apache Tomcat 文件包含漏洞 (CVE20201938) 复现
  • 原文地址:https://www.cnblogs.com/MissSage/p/14878903.html
Copyright © 2011-2022 走看看