目录
2.聚合操作reduce,reduceLeft,reduceRight使用详解
3.fold,foldLeft,foldRight的使用详解
0.Scala函数式编程
我们将来使用Spark/Flink的大量业务代码都会使用到函数式编程。下面这些事开发中常用的函数式编程。注意这些函数都是操作 Scala 集合的,一般会进行两类操作:转换操作(transformation )和行动操作(actions)(有些人喜欢叫他为聚合操作)。第一种操作类型将集合转换为另一个集合,第二种操作类型返回某些类型的值。
- 遍历( foreach )
- 映射( map )
- 映射扁平化( flatmap )
- 过滤( filter )
- 是否存在( exists )
- 排序( sorted 、 sortBy 、 sortWith )
- 分组( groupBy )
- 聚合计算( reduce )
- 折叠( fold )
1.filter过滤的使用详解
filter过滤出集合中符合特定条件的子集,实际上,过滤是一个转换类型的方法,但是比运用 min和 max方法简单。
【1.1语法结构】
【1.2执行过程】
【1.3使用演示】
//过滤filter
scala> List(1,2,3,4,5,6,7,8,9).filter(_ % 2 == 0)
res8: List[Int] = List(2, 4, 6, 8)
//复杂点的filter过滤,过滤页数大于120页码的
case class Book(title: String, pages: Int)
val books = Seq(
Book("Future of Scala developers", 85),
Book("Parallel algorithms", 240),
Book("Object Oriented Programming", 130),
Book("Mobile Development", 495)
)
println( books.filter(book => book.pages >= 120))
//ArrayBuffer(Book(Parallel algorithms,240), Book(Object Oriented Programming,130), Book(Mobile Development,495))
2.聚合操作reduce,reduceLeft,reduceRight使用详解
聚合操作,可以将一个列表中的数据合并为一个。这种操作经常用来统计分析中。而map是对集合的元素进行加工操作,不改变集合的结构。
【2.1 语法结构】
reduce表示将列表,传入一个函数进行聚合计算
尖叫提示:
- reduce传入的也是一个函数,只是这个函数要传入两个参数。
- 其实就是迭代,reduceLeft函数表示从左聚合操作,reduceRight表示从右聚合。
【2.2 执行流程】
尖叫提示: 如上,首先元素1和元素2作为两个参数,传递给reduce聚合函数。然后参数1,参数2在聚合函数聚合以后做为一个新的参数和参数3一起传递给reduce进行聚合计算,依次类推,直到最后一个元素作为参数传递完为止。
【2.3使用演示】
//标准函数版reduce
val ar = List(1,2,3,4,5)
println( ar.reduce((x,y)=>x+y)) //15求和
println(ar.reduce((x,y)=>1*x-2*y)) //-27
println(ar.reduceLeft((x,y)=>x-y)) // -13
println(ar.reduceRight((x,y)=>x-y)) //3 特别注意reduceRight的计算逻辑 1-(2-(3-(4-5)))
// 第一个下划线表示第一个参数,就是历史的聚合数据结果
// 第二个下划线表示第二个参数,就是当前要聚合的数据元素
println(ar.reduce(_+_)) //求和 15
println(ar.reduceRight(_-_)) //3
println(ar.reduceLeft(_+_)) //15
println(ar.reduce(_*1-_*2)) //-27
3.fold,foldLeft,foldRight的使用详解
fold与reduce基本一样,只是多了一个指定初始值参数,注意这个时候计算从初始值开始,而不是第一个元素开始。
【3.2使用演示】
val ar1 = List(1, 2, 3, 4, 5)
println(ar1.fold(0)(_ + _)) //求和,给个求和的初始值0,15
println(ar1.fold(100)(_ + _)) //求和,给个求和的初始值100,结果115
println(ar1.foldLeft(0)(_-_)) //-15 0-1-2-3-4-5.注意这个和reduceLeft的别,有个初始值。
println(ar.reduceLeft(_-_)) //-13