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

高阶函数,是指以一个函数作为输入或输出的函数。我们常用的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的人有所帮助。

猜你喜欢

转载自blog.csdn.net/kwame211/article/details/80912007
今日推荐