Scala容器中的高阶函数 | Hello Code

文章目录
  1. 1. List
    1. 1.1. aggregate
    2. 1.2. andThen
    3. 1.3. collect
    4. 1.4. collectFirst
    5. 1.5. compose
    6. 1.6. corresponds
    7. 1.7. count
    8. 1.8. dropWhile
    9. 1.9. exists
    10. 1.10. filter
    11. 1.11. filterNot
    12. 1.12. find
    13. 1.13. flatten
    14. 1.14. fold
    15. 1.15. forall
    16. 1.16. foreach
    17. 1.17. groupBy
    18. 1.18. indexWhere
    19. 1.19. map
    20. 1.20. maxBy
    21. 1.21. minBy
    22. 1.22. partition
    23. 1.23. prefixLength
    24. 1.24. reduce
    25. 1.25. reduceOption
    26. 1.26. reverseMap
    27. 1.27. runWith
    28. 1.28. scan
    29. 1.29. sortWith
    30. 1.30. span
    31. 1.31. takeWhile
  2. 2. 后记
  3. 3. 参考资料

高阶函数,是指以一个函数作为输入或输出的函数。我们常用的Curry化函数,就是输出一个函数的高阶函数。

在Scala中,容器包含了丰富的高阶函数,从经典的map-reduce,到晦涩的aggregate,应有尽有。虽然初看起来过于复杂, 但是它在提高代码重用性,以及封装并发性等方面,却有不可替代的作用,十分值得我们学习。

List

List类几乎包含了Scala集合框架中所有的高阶函数,所以我们使用它作为样例来分析高阶函数。
在它的文档中,可以看到所有List的所有方法。这里按照文档的顺序来一一说明其意义。

声明在前,这里所有的方法都是非破坏性方法,也就是说,它们不改变容器的内容。

aggregate

  • 作用:一个比fold、reduce更加抽象的聚集操作,对集合分块,块中每一个元素执行一个操作,得到一个容器,在将这些容器进行聚集。
  • 样例:
    1
    2
    3
    4
    
    // 求容器所有元素mod之后的Set
    val list = List(1, 4, 9)
    list.aggregate(scala.collection.mutable.Set[Int]())(_ += _ % 8, _ ++ _)
    // return: Set[Int] = Set(1, 4)
    

andThen

  • 作用:把两个函数组合在一起,先调用第一个函数,再调用第二个。
  • 样例:
    1
    2
    3
    4
    5
    6
    
    // 先调用add2, 再调用add3
    def add2(num: Int) = num + 2
    def print(num: Int) = println(num)
    val addAndPrint = add2 _ andThen print _
    addAndPrint(2)
    //return: 4
    

collect

  • 作用:基于给定的偏函数,遍历容器,得到一个新的容器。(此函数十分强大)
  • 样例:
    1
    2
    3
    4
    
    // 找到列表中的奇数,乘以2
    val list = List(1, 4, 9)
    list collect { case item if item % 2 == 1 => item * 2 }
    // return: List[Int] = List(2, 18)
    

collectFirst

  • 作用:基于给定的偏函数,查找第一个满足此条件的元素。
  • 样例:

    1
    2
    3
    
    // 找到第一个奇数,乘以2
    val list = List(1, 4, 9)
    list collectFirst { cast item if item % == 1 => item * 2} getOrElse 0
    

compose

  • 作用:把两个函数组合在一起,形成一个新的函数。
  • 样例:
    1
    2
    3
    4
    5
    6
    
    // 把两个函数组合
    def add2(num: Int) = num + 2
    def add3(num: Int) = num + 3
    val add5 = add2 _ compose add3 _
    add5(1)
    // return: Int = 6
    

corresponds

  • 作用:测试两个容器所有相应的元素时候满足一定的关系。
  • 样例:
    1
    2
    3
    4
    5
    
    // 判断两个列表的元素是否满足两倍的关系
    val list1 = List(1, 4, 9)
    val list2 = List(2, 8, 18)
    list1.corresponds(list2){_ * 2 == _}
    // return : Boolean = true
    

count

  • 作用:计数满足条件的元素
  • 样例:
    1
    2
    3
    4
    
    // 计数偶数的个数
    val list = List(1, 4, 9)
    list.count(_ % 2 == 0)
    // return : Int = 1
    

dropWhile

  • 作用:以指定的条件删除满足条件的最长前缀
  • 样例:
    1
    2
    3
    4
    
    // 删除小于8 的前缀
    val list = List(1, 4, 9)
    list.dropWhile(_ < 8)
    // return: List[Int] = List(9)
    

exists

  • 作用:判断容器中是否存在满足条件的元素
  • 样例:
    1
    2
    3
    4
    
     // 判断是否存在偶数
    val list = List(1, 4, 9)
    list.exists(_ % 2 == 0)
    // return : Boolean = true
    

filter

  • 作用:以指定的条件过滤容器
  • 样例:
    1
    2
    3
    4
    
    // 返回偶数
    val list = List(1, 4, 9)
    list.filter(_ % 2 == 0)
    //return : List[Int] = List(2)
    

filterNot

  • 作用:反向过滤容器
  • 样例:
    1
    2
    3
    4
    
    // 返回奇数
    val list = List(1, 4, 9)
    list.filterNot(_ % 2 == 0)
    // return : List[Int] = List(1, 9)
    

find

  • 作用:在容器中查找元素
  • 样例:
    1
    2
    3
    4
    
    // 查找偶数
    val list = List(1, 4, 9)
    list.find(_ % 2 == 0)
    // return : Option[Int] = Some(2)
    

flatten

  • 作用:将容器扁平化
  • 样例:
    1
    2
    3
    4
    
    // 扁平化
    val list = List(List(2, 3), List(4, 5))
    list.flatten
    // return: List[Int] = List(2, 3, 4, 5)
    

fold

  • 作用:“折叠容器”,给定初始值,以及折叠方法。或称统计,一般用来统计某个特征。
  • 样例:
    1
    2
    3
    
    // 求10的阶乘
    (1 to 10).fold(1)(_ * _)
    // return: Int = 3628800
    

forall

  • 作用:测试容器中的每一个元素
  • 样例:
    1
    2
    3
    
    val list = List(1, 4, 9)
    list.forall(_ % 2 == 0)
    //return : Boolean = false
    

foreach

  • 作用:以容器中的每一个元素为参数调用函数,无返回值。
  • 样例:
    1
    2
    3
    4
    
    // 打印容器
    val list = List(1, 4, 9)
    list.foreach(println)
    // return :
    

groupBy

  • 作用:以指定的条件来对容器中的元素分组,得到一个Map。
  • 样例:
    1
    2
    3
    4
    
    // 以 mod 8 的结果来对容器的元素分组
    val list = List(1, 4, 9)
    list groupBy (_ % 8)
    // return: scala.collection.ummutable.Map[Int, List[Int]] = Map(4 -> List(4), 1 -> List(1, 9))
    

indexWhere

  • 作用:查找满足条件的元素的索引
  • 样例:
    1
    2
    3
    4
    
    // 查找第一个偶数的位置
    val list = List(1, 4, 9)
    list.indexWhere(_ % 2 == 0)
    // return: Int = 1
    

map

  • 作用:以容器中每一个元素为参数调用函数,返回新容器
  • 样例:
    1
    2
    3
    4
    
    // 将容器中的元素 * 2
    val list = List(1, 4, 9)
    list.map(_ * 2)
    // return : List[Int] = List(2, 8, 18)
    

maxBy

  • 作用:以指定的条件来衡量每个元素的价值,找价值最大的。
  • 样例:
    1
    2
    3
    4
    
    // 找mod 7之后最大的元素
    val list = List(1, 4, 9)
    list.maxBy(_% 7)
    // return: Int = 4
    

minBy

  • 作用:以指定的条件衡量每个元素的价值,找价值最小的。
  • 样例:
    1
    2
    3
    
    // 找mod 7 之后最小的元素
    val list = List(1, 4, 9)
    // return: Int = 1
    

partition

  • 作用:按照指定的条件,将容器分成两部分,前一部分满足条件,后半部分不满足。
  • 样例:
    1
    2
    3
    4
    
    // 将奇数和偶数分离
    val list = List(1, 4, 9)
    list.partition(_ % 2 == 0)
    // return : (List[Int], List[Int]) = (List(4), List(1, 9))
    

prefixLength

  • 作用:计算满足长度的最长前缀的长度
  • 样例:
    1
    2
    3
    4
    
    // 从前往后满足小于8的前缀的长度
    val list = List(1, 4, 9)
    list.prefixLength(_ < 8)
    //return : Int = 2
    

reduce

  • 作用:规约,对容器中的每两个元素进行一次二元操作,直到只剩下最后一个元素,其顺序不固定。
  • 样例:
    1
    2
    3
    4
    
    // 计算元素的和
    val list = List(1, 4, 9)
    list.reduce(_ + _)
    // return: Int = 14
    

reduceOption

  • 作用:规约,对容器中每两个元素执行二元操作,知道只剩下最后一个元素,返回Option。
  • 样例:
    1
    2
    3
    4
    
    // 计算元素的积
    val list = List(1, 4, 9)
    list.reduceOption(_ * _)
    // return: Option[Int] = Some(36)
    

reverseMap

  • 作用:逆序执行Map
  • 样例:
    1
    2
    3
    4
    
    // 逆序列表并乘以2
    val list = List(1, 4, 9)
    list.reverseMap(_ * 2)
    // return: List[Int] = List(18, 8, 2)
    

runWith

  • 作用:执行偏函数,当参数不在定义域内时,返回false,否则返回true,并执行action。
  • 样例:
    1
    2
    3
    4
    5
    6
    
    // 偏函数将奇数*2,然后打印结果
    val pf: PartialFunction[Int, Int] = { case m: Int if m % 2 == 1=> m * 2 }
    pf.runWtih(println)(3)
    // return: Boolean = true
    pf.runWith(println)(2)
    // return: Boolean = false
    

scan

  • 作用:折叠,与fold的动作类似,但会将每一次折叠的结果存放到另一个容器中,然后那个容器。
  • 样例:
    1
    2
    3
    
    // 求1-10的阶乘
    (1 to 10).scan(1)(_ * _)
    //return :scala.collection.immutable.IndexedSeq[Int] = Vector(1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800)
    

sortWith

  • 作用:用指定的函数排序
  • 样例:
    1
    2
    3
    4
    
    // 倒排
    val list = List(1, 4, 9)
    list.sortWith(_ > _)
    // return: List[Int] = List(9, 4, 1)
    

span

  • 作用:以指定的条件切分列表,满足条件的最长前缀和其余的部分作为一个元组返回。
  • 样例:
    1
    2
    3
    4
    
    // 查找小于8的前缀,以及剩下部分
    val list = List(1, 4, 9)
    list span(_ < 8)
    // return : (List[Int], List[Int]) = (List(1, 4), List(9))
    

takeWhile

  • 作用:以指定的条件截取最长的前缀
  • 样例:
    1
    2
    3
    4
    
    // 小于8的前缀
    val list = List(1, 4, 9)
    list.takeWhile(_ < 8)
    // return: List[Int] = List(1, 4)
    

后记

前后一共花了三天时间才搞定这个文档,从一开始对这些函数一无所知,翻阅各种文档,在StackOverFlow上找结果,最终还是搞定了这个文档。当然,这个函数创造的本意是提高效率,而不是为了学习这些函数而学习。目前还没有对容器中高阶函数的详细介绍,希望这个文档能对学习Scala的人有所帮助。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值