Scala之高阶函数指南
高阶函数是指使用其他函数作为参数、或者返回一个函数作为结果的函数。在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))