Scala系列-2、scala函数式编程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

传送门:大数据系列文章目录

Scala系列-2、scala函数式编程

目录

*
foreach算子
映射 | map 算子
扁平化映射 | flatMap
过滤 | filter
排序操作: 指定字段排序 | sortBy
排序操作: 自定义排序 | sortWith
分组 | groupBy
聚合操作 | reduce
聚合操作 | fold

所谓函数式编程, 主要指的是, 在调用一个方法的时候, 可以将函数作为一个方法的参数, 传递到方法中, 这样的操作称为函数式编程, 在scala中提供了非常的可以支持函数式编程的方法

  • 遍历( foreach
  • 映射( map
  • 映射扁平化( flatmap
  • 过滤( filter
  • 是否存在( exists
  • 排序( sortedsortBysortWith
  • 分组( groupBy
  • 聚合计算( reduce
  • 折叠( fold

注意: 习惯性将支持函数式编程的方法, 称为算子

; foreach算子

foreach算子主要的作用 : 用于对集合进行遍历操作

调用方法的参数传递的格式

foreach(f: (A) ⇒ Unit): Unit

示例

有一个列表,包含以下元素1,2,3,4,请使用foreach方法遍历打印每个元素

val list1  = List(1,2,3,4)

基于for循环:
for( i  list1 ) println(i)

基于foreach算子操作:

list1.foreach((i:Int) =>  println(i) );

其实通过函数传递的一般都是操作的规则, 具体要怎么做内容

以上操作是可以进行简写的:
1) 对于函数的参数类型, 一般是可以省略的, 因为在调用foreach方法时候, scala会自动推断类型
2) 如果函数的参数只有一个, () 也是可以省略的
list1.foreach( i =>  println(i) );

上述操作 依然还是可以进行简写:
1) 如果 参数在 函数体中仅使用了一次, 可以直接使用 _ 替代即可 , 不需要在定义变量了
list1.foreach( println(_) );

底层是如何实现的:

list1.foreach((i:Int) =>  println(i) );

def foreach ( val f1:Int => Unit ) {

    for( i  list1  ){
        f1(i)
    }

}

原始调用一个函数
val f1 =  (i:Int) =>  println(i)
for(i  list1 ){
    f1(i)
}

Scala系列-2、scala函数式编程

映射 | map 算子

MR 中 map的作用是什么?当然是接收 k1和v1 负责将其转换为 k2和v2

在scala中 map算子 主要负责将数据进行一对一的转换操作, 在转换的时候, 执行一些转换操作, 特点输入进去几个值, 就会输出几个值

格式:

def map[B](f: (A) ⇒ B): TraversableOnce[B]

案例一

  1. 创建一个列表,包含元素1,2,3,4
  2. 对List中的每一个元素加1
val list1  = List(1,2,3,4)

list1.map( i => i+1 )

简写:
list1.map( _+1 )

输出:
List(2,3,4,5)

扁平化映射 | flatMap

功能: flatMap 主要是用于将数据转换为另一种方式

​ 此操作: 将 map 和 flatten 合并在一起的操作形式

示例1:

假设目前有这么一份数据:

“张三 李四”, “王五 赵六” , “田七 周八” , 需要转换为 张三 李四 王五 赵六 田七 周八

val list2 = List("张三 李四","王五 赵六","田七 周八")

原生写法:
list2.map(i => i.split(" ") )
结果:
   res7: List[Array[String]] = List(Array(张三, 李四), Array(王五, 赵六), Array(田七, 周八))

res7.flatten
结果:
res8: List[String] = List(张三, 李四, 王五, 赵六, 田七, 周八)

以上两步 可以通过  flatMap解决:
list2.flatMap( i => i.split(" "))
简写:
list2.flatMap( _.split(" "))
结果内容:
res9: List[String] = List(张三, 李四, 王五, 赵六, 田七, 周八)

过滤 | filter

作用: 对数据进行过滤, 将符合条件的数据获取出来即可

格式:

def filter(p: (A) ⇒ Boolean): TraversableOce[A]

表示 : 在函数中进行数据判断, 如果判断为true 表示需要此数据, 如果为false 表示此数据直接过滤掉

示例

将 1~10之间的偶数获取出来

val list3 = 1 to 10;

list3.filter( i =>  if(i % 2 == 0) true else false )

简写:
list3.filter( i =>  i % 2 == 0 )
||
||
list3.filter( _ % 2 == 0)

排序操作: 指定字段排序 | sortBy

作用: 根据字段的进行排序的操作

格式:

def sortBy[B](f: (A) ⇒ B): List[A]

示例:

比如 目前有这么一份数据:

​ “张三 20” “李四 15” “赵六 23” “田七 40” “周八 99”

要求请按照 年龄的升序排序

val list4 = List("张三 20","李四 15","赵六 23","田七 40","周八 99")

list4.sortBy( i => i.split(" ")(1))

list4.sortBy( i => i.split(" ")(1)).reverse

排序操作: 自定义排序 | sortWith

作用: 自定义其排序内容

格式:

def sortWith(lt: (A, A) ⇒ Boolean): List[A]

注意:
    在自定义排序中, 参数是有两个值, 这个两个值就是列表中相邻的两个元素, 对元素进行两两比较, 然后进行比较处理即可

示例:

  1. 有一个列表,包含以下元素:2,3,1,6,4,5
  2. 使用sortWith对列表进行降序排序

val list4 = List(2,3,1,6,4,5)

list4.sortWith( (a1,a2) => a1 > a2 )

简写:
list4.sortWith( _ < _ )

分组 | groupBy

作用: 根据指定的字段执行分组操作, 将相同组的数据放置在一起

格式:

def groupBy[K](f: (A) ⇒ K): Map[K, List[A]]

示例:

比如目前有一份单词数据: hadoop hive hadoop sqoop hadoop hive hive hbase, 要求计算其每个单词的出现次数

val list5 = List("hadoop hive hadoop sqoop hadoop hive hive hbase")

操作:
    list5.flatMap( i => i.split(" "))
    结果:
    res24: List[String] = List(hadoop, hive, hadoop, sqoop, hadoop, hive, hive, hbase)

    res24.map(i => i -> 1 )

    结果:
        res25: List[(String, Int)] = List((hadoop,1), (hive,1), (hadoop,1), (sqoop,1), (hadoop,1), (hive,1), (hive,1), (hbase,1))

    res25.groupBy(i =>i._1)

    结果:
        res26: scala.collection.immutable.Map[String,List[(String, Int)]] = Map(hadoop -> List((hadoop,1), (hadoop,1), (hadoop,1)), sqoop -> List((sqoop,1)), hive -> List((hive,1), (hive,1), (hive,1)), hbase -> List((hbase,1)))

    res26.map( i => i._1 -> i._2.size )

    结果:
        res27: scala.collection.immutable.Map[String,Int] = Map(hadoop -> 3, sqoop -> 1, hive -> 3, hbase -> 1)

进行合并操作:
    list5.flatMap( i => i.split(" ")).map(i => i -> 1 ).groupBy(i =>i._1).map( i => i._1 -> i._2.size )

进行简写:
    list5.flatMap( _.split(" ")).map(_ -> 1 ).groupBy(_._1).map( i => i._1 -> i._2.size )
结果:
    res28: scala.collection.immutable.Map[String,Int] = Map(hadoop -> 3, sqoop -> 1, hive -> 3, hbase -> 1)

聚合操作 | reduce

作用: 帮助实现聚合操作, 注意此聚合不含分组操作

格式:

def reduce[A1 >: A](op: (A1, A1) ⇒ A1): A1
扩展:
    reduceLeft  此方法与  reduce一致的 都是从左往右计算聚合
    reduceRight  从右往左计算聚合

说明:
    此方法, 需要传递的函数具备两个参数:
            参数1: 局部累加聚合结果
            参数2: 每一次遍历出来的元素

示例

  1. 定义一个列表,包含以下元素:1,2,3,4,5,6,7,8,9,10
  2. 使用reduce计算所有元素的和
val list6 = 1 to 10

list6.reduce((agg,curr) => agg + curr)

list6.reduce((agg,curr) => {
    println(agg+"   "+ curr)
    agg + curr
})

scala> list6.reduce((agg,curr) => {
     |     println(agg+"   "+ curr)
     |     agg + curr
     | })
1   2
3   3
6   4
10   5
15   6
21   7
28   8
36   9
45   10
res34: Int = 55
简写:
list6.reduce(_+_)

聚合操作 | fold

作用: 与reduce是一致的, 只比reduce的操作多了一个初始值

格式:

def fold[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1

示例

  1. 定义一个列表,包含以下元素:1,2,3,4,5,6,7,8,9,10
  2. 使用reduce计算所有元素的和
val list6 = 1 to 10

list6.fold(100)((agg,curr) => agg + curr)

list6.fold(100)((agg,curr) => {
    println(agg+"   "+ curr)
    agg + curr
})
100   1
101   2
103   3
106   4
110   5
115   6
121   7
128   8
136   9
145   10
res36: Int = 155

注意:
    通过 fold 可以设置 agg初始值, 默认情况下, 初始值是集合的第一个元素

Original: https://blog.csdn.net/l848168/article/details/127805554
Author: 技术武器库
Title: Scala系列-2、scala函数式编程

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/656870/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球