已复制
全屏展示
复制代码

Scala之高阶函数指南


· 3 min read

高阶函数是指使用其他函数作为参数、或者返回一个函数作为结果的函数。在Scala中函数是“一等公民”,所以允许定义高阶函数。这里的术语可能有点让人困惑,我们约定,使用函数作为参数,或者返回值为函数的“函数”和“方法”,均称之为“高阶函数”。

一. map

将传入的函数一次作用在序列上

val list = List(1, 2, 3, 4)
list.map(_ * 10)            // List(10, 20, 30, 40)

二. reduce

reduceLeft

val list = List(1, 2, 3, 4)
list.reduceLeft((x,y) => (x-y))    // 1-2-3-4 = -8

reduceRight

val list = List(1, 2, 3, 4)
list.reduceRight((x,y) => (x-y))   // 4-3-2-1 = -2

reduce

reduce 默认是使用 reduceLeft,reduce的初始值就是第一个数。

val list = List(1, 2, 3, 4)
list.reduce((x,y) => (x-y))        // 1-2-3-4 = -8

三. fold

fold和reduce类似,但是fold操作需要从一个初始开始。

foldLeft

val list = List(1, 2, 3, 4)
list.foldLeft(10)((x,y) => (x-y)) // 0

foldRight

val list = List(1, 2, 3, 4)
list.foldRight(10)((x,y) => (x-y)) // 8
// 计算方式如下
// 10 = 10
// 4 - 10 = -6
// 3 - (-6) = 9
// 2 - 9 = -7
// 1 - (-7) = 8

fold

fold 默认是使用 foldLeft

val list = List(1, 2, 3, 4)
list.fold(10)((x,y) => (x-y))    // 0

四. filter

将传入的函数应用到每个元素,返回true则保留

val list = List(1, 2, 3, 4)
list.filter(_ % 2 == 0)        // List(2, 4)

五. flatten

将最外层的序列的每个元素取出,组成一个新的序列返回

val list = List(List(1,2,3), List(4,5,6))
list.flatten                // List(1, 2, 3, 4, 5, 6)

六. flatMap

先执行 map 再执行 flatten


val list = List(List(1,2,3), List(4,5,6))
list.flatMap(x => x.map(_*10))    // List(10, 20, 30, 40, 50, 60)

val hello = List("java scala java python", "where are you from")
hello.flatMap(x => x.split(" "))  // List(java, scala, java, python, where, are, you, from)

七. scan

scan 和reduce 相似,不同点在于:reduce返会所有的值运算,而scan返回的结构原始结构一样。

val list = List(1,2,3,4,5,6)
list.scan(0)((x,y)=>x+y)  // List(0, 1, 3, 6, 10, 15, 21)

// 计算过程如下
// 0
// 0 + 1
// 0 + 1 + 2
// 0 + 1 + 2 + 3
// 0 + 1 + 2 + 3 + 4
// 0 + 1 + 2 + 3 + 4 + 5
// 0 + 1 + 2 + 3 + 4 + 5 + 6

八. sorted

  • 默认排序规则
val list = List("z", "a", "B", "C")
println(list.sorted)  

// List(B, C, a, z)
  • 自定义隐式排序规则
implicit val KeyOrdering: Ordering[String] = new Ordering[String] {
  override def compare(x: String, y: String): Int = {
    x.compareToIgnoreCase(y)
  }
}
val list = List("z", "a", "B", "C")
println(list.sorted)  // List(a, B, C, z)

九. sortWith

// 正序
val list = List(1,5,6,5,1,8,9)
list.sortWith((x1,x2) => x1<x2)  // List(1, 1, 5, 5, 6, 8, 9)

// 倒序
val list = List(1,5,6,5,1,8,9)
list.sortWith((x1,x2) => x1>x2)  // List(9, 8, 6, 5, 5, 1, 1)

十. sortBy

// 升序
case class Person(name: String, age: Int)
val list = List(Person("zhang", 22), Person("wang", 34), Person("li", 19))
list.sortBy(x=>x.age)  
// List(Person(li,19), Person(zhang,22), Person(wang,34))


// 倒序
implicit val KeyOrdering: Ordering[Int] = new Ordering[Int] {
  override def compare(x: Int, y: Int): Int = {
    y - x
  }
}
case class Person(name: String, age: Int)
val list = List(Person("zhang", 22), Person("wang", 34), Person("li", 19))
list.sortBy(x=>x.age)  
// List(Person(wang,34), Person(zhang,22), Person(li,19))
🔗

文章推荐