Scala入门9之函数高级操作【字符串高级操作、匿名函数、柯里化(Currying)函数、高阶函数】

1、字符串高级操作

1.1 定义字符串

\quad \quad scala提供多种定义字符串的方式,将来我们可以根据需要来选择最方便的定义方式。

  • 使用双引号
  • 使用三引号

使用双引号——适用于少量内容

语法

var/val 变量名="字符串”

使用三引号

\quad \quad 如果有大段的文本需要保存,就可以使用三引号来定义字符串。例如:保存一大段的SQL语句。三 个引号中间的所有字符串都将作为字符串的值。

语法

val/var 变量名 = """字符串1
 字符串2"""
  • 快捷技巧:shift+分号按三下就能出现三引号

例子:

object StringApp extends App {

  val b =
    """
      |这是一个多行字符串
      |hello
      |word
      |""".stripMargin

  println(b)

  
}

结果:

在这里插入图片描述

1.2 字符串拼接

字符串拼接有两种方式:

  • + :以前,字符串的拼接我们往往使用+来拼接
  • 插值法:
    语法
s"${字符串1}${字符串2}"// 大括号可以省略

例子:

object StringApp extends App {
  val s="Hello:"
  val name="PK"

  println(s)
  println(s+name)
  // 插值
  println(s"$s$name")
}

结果:
在这里插入图片描述

2、匿名函数

\quad \quad 在Scala中,你不需要给每一个函数命名,没有将函数赋给变量的函数叫做匿名函数。

语法

(参数名:参数类型)=>函数体

例子:

scala> (x:Int) => x+1
res7: Int => Int = <function1>

匿名函数的作用

  • 可以将匿名函数传给一个变量,变量就可以为一个函数使用
scala> val m1=(x:Int) => x+1
m1: Int => Int = <function1>
scala> m1(10)
res8: Int = 11
  • 可以将匿名函数传给方法(函数)作为方法的参数使用
scala> def add=(x:Int,y:Int) => {x+y}
add: (Int, Int) => Int

scala> add(2,3)
res9: Int = 5

3、柯里化(Currying)函数

\quad \quad 柯里化(Currying)指的是把原来接受多个参数的函数变换成接受一个参数的函数过程,并且返回接受余下的参数且返回结果为一个新函数的技术。

语法

def 函数名(参数1:参数1类型)(参数2:参数2类型):返回值类型={
// 代码块
}
  • 返回值类型可以不写
    例子
object StringApp extends App {
  //非柯里化(Currying)函数
  def sum(a:Int,b:Int)=a+b
  println(sum(2,3))
  //柯里化(Currying)函数
  def sum2(a:Int)(b:Int)=a+b
  println(sum2(2)(3))

}
  • scala柯里化风格的使用可以简化主函数的复杂度,提高主函数的自闭性,提高功能上的可扩张性、灵活性。可以编写出更加抽象,功能化和高效的函数式代码。

4、高阶函数

4.1 Map(映射)函数

定义/方法签名

在这里插入图片描述
用途:

\quad \quad 将函数f应用于数组的所有元素,并返回一个新的数组B。函数f输入类型为A,返回值类型为B。

例子:

  val l = List(1,2,3,4)
  //map:逐个去操作集合中的每个元素
  l.map((x:Int) => x+1)
  // map会自动辨别x的类型,所以可省略参数类型
  l.map((x)=>x+1)
  // 当参数元素只有一个时,可以省略括号,但如果有两个,就不能省略
  l.map(x=>x+1)
  // 下划线代表每一个元素
  l.map(_+1)

在这里插入图片描述

  • 数组、列表类型都有map函数,用法都一样
  • Map类型的map函数使用
scala> Map("Spark"->1,"Hive"->2,"hadoop"->2).map(_._1)
res31: scala.collection.immutable.Iterable[String] = List(Spark, Hive, hadoop)

scala> Map("Spark"->1,"Hive"->2,"hadoop"->2).map(_._2)
res32: scala.collection.immutable.Iterable[Int] = List(1, 2, 2)

scala>  Map("Spark"->1,"Hive"->2,"hadoop"->2).map(x=>x._1)
res33: scala.collection.immutable.Iterable[String] = List(Spark, Hive, hadoop)

  • 集合的映射操作是将来在编写Spark/Flink用得最多的操作,是我们必须要掌握的掌握。

4.2 flatMap函数(扁平化映射)

定义/方法签名

在这里插入图片描述

用途
\quad \quad 将函数f作用于集合中的所有元素,各元素得到相应的集合,然后再将其扁平化返回,生成新的集合

  • 可以把flatMap,理解为先map,然后再flatten
  • map是将列表中的元素转换为一个List
  • flatten 再将整个列表进行扁平化

例1:

scala> var f=List(List(1,2),List(3,4),List(5,6))
f: List[List[Int]] = List(List(1, 2), List(3, 4), List(5, 6))
scala> f.flatMap(_.map(_*2))
res28: List[Int] = List(2, 4, 6, 8, 10, 12)

其实也就相当于

scala> var f=List(List(1,2),List(3,4),List(5,6))
f: List[List[Int]] = List(List(1, 2), List(3, 4), List(5, 6))
scala> f.map(_.map(_*2)).flatten
res36: List[Int] = List(2, 4, 6, 8, 10, 12)

例2:

  • 有一个包含了若干个文本行的列表:“hadoop hive spark flink flume”, “kudu hbase sqoop storm”

  • 需求:获取到文本行中的每一个单词,并将每一个单词都放到列表中

  • 思路:

在这里插入图片描述
第一种方法:map+flatten

  • 使用map将文本行拆分成数组
  • 再对数组进行扁平化
// 定义文本行列表
scala> val line=List("hadoop hive spark flink flume","kudu hbase sqoop storm")
line: List[String] = List(hadoop hive spark flink flume, kudu hbase sqoop storm)
// 使用map函数将文本行转换为单词数组
scala> line.map(_.split(" "))
res39: List[Array[String]] = List(Array(hadoop, hive, spark, flink, flume), Array(kudu, hbase, sqoop, storm))
// flatten亚平
scala> line.map(_.split(" ")).flatten
res40: List[String] = List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm)

第二种方法:使用flatMap函数

scala> val line=List("hadoop hive spark flink flume","kudu hbase sqoop storm")
line: List[String] = List(hadoop hive spark flink flume, kudu hbase sqoop storm)
scala> line.flatMap(_.split(" "))
res42: List[String] = List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm)


4.3 flatten(扁平)函数

  • 可将含有多个列表的列表亚平,转化为一个列表
scala> var f=List(List(1,2),List(3,4),List(5,6))
f: List[List[Int]] = List(List(1, 2), List(3, 4), List(5, 6))

scala> f.flatten
res2: List[Int] = List(1, 2, 3, 4, 5, 6)

4.4 filter(过滤)函数

\quad \quad 过滤符合一定条件的元素

定义/方法签名
在这里插入图片描述

用途
\quad \quad 返回所有满足条件p的元素集合

例子

// 定义一个列表
scala> val listInt=List(1,4,6,8,13)
listInt: List[Int] = List(1, 4, 6, 8, 13)
//返回所有元素值大于6的元素构成的集合
scala> listInt.filter(x=>x>6)
res3: List[Int] = List(8, 13)
//简化写法
scala> listInt.filter(_>6)
res4: List[Int] = List(8, 13)

4.5 reduce函数

\quad \quad 一 一 对相邻元素进行相同操作
定义/方法签名

def reduce[A1>:A](op:(A1,A1) => A1):A1
reduce 方法API说明
泛型[A1>:A](下界)A1必须是集合元素类型的子类
参数op:(A1,A1) => A1传入函数对象,用来不断进行折叠操作,第一个A1类型参数为当前折叠后的变量,第一个A1类型参数为当前要进行折叠的元素
返回值A1列表最后折叠为一个元素

用途
\quad \quad 使用函数op作用于集合之上,返回的结果类型为A1.op为特定的联合二元算子,A1为A的超类。

  • 下面通过一个例子方便理解一下reduce函数
scala> Array(1,2,3,4,5).reduce((x:Int,y:Int)=>{println(x,y);x+y})
(1,2)
(3,3)
(6,4)
(10,5)
res5: Int = 15
  • 此例子就是数组中两两相邻元素依次相加,得到的结果再与数组中下一个元素相加,直到数组中没有元素为止。 reduce函数相当于sum函数

  • 上面的语法太麻烦了,其实可以简化一下

scala> Array(1,2,3,4,5).reduce(_+_)
res6: Int = 15

reduce函数变种

\quad \quad reduce函数还有两个函数变种,分别是reduceLeft和reduceRight。

  • reduceLeft:指的是op函数按集合中元素的顺序从左到右对其进行reduce操作,且得到的结果放在左边,数组下一个元素放在右边。等价于reduce函数
scala> Array(1,2,3,4,5).reduceLeft((x:Int,y:Int)=>{println(x,y);x+y})
(1,2)
(3,3)
(6,4)
(10,5)
res7: Int = 15

  • reduceRight:指的是op函数按集合中元素的顺序从右到左对其进行reduce操作,且得到的结果放在右边,数组下一个元素放在左边。
scala> Array(1,2,3,4,5).reduceRight((x:Int,y:Int)=>{println(x,y);x+y})
(4,5)
(3,9)
(2,12)
(1,14)
res8: Int = 15
  • 其实对于两两相加,reduceLeft和reduceRight函数得到的结果一样
  • 但是对于两两相减,reduceLeft和reduceRight函数得到的结果不一样
scala> Array(1,2,3,4,5).reduceLeft((x:Int,y:Int)=>{println(x,y);x-y})
(1,2)
(-1,3)
(-4,4)
(-8,5)
res11: Int = -13


scala> Array(1,2,3,4,5).reduceRight((x:Int,y:Int)=>{println(x,y);x-y})
(4,5)
(3,-1)
(2,4)
(1,-2)
res13: Int = 3
  • 简化写法
scala> Array(1,2,3,4,5).reduceLeft(_-_)
res9: Int = -13

scala> Array(1,2,3,4,5).reduceRight(_-_)
res10: Int = 3

4.6 fold(折叠)函数

\quad \quad 与reduce很像,但是多了一个指定初始化值参数。

定义/方法签名

def fold[A1>:A](z:A1)(op:(A1,A1) => A1):A1
reduce 方法API说明
泛型[A1>:A](下界)A1必须是集合元素类型的子类
参数1(z:A1)初始值
参数2op:(A1,A1) => A1传入函数对象,用来不断进行折叠操作,第一个A1类型参数为当前折叠后的变量,第一个A1类型参数为当前要进行折叠的元素
返回值A1列表最后折叠为一个元素

用途
\quad \quad 使用联合二元操作算子op对集合进行折叠操作,z为给定的初始值

例子

scala> Array(1,2,3,4,5).fold(0)((x:Int,y:Int)=>{println(x,y);x+y})
(0,1)
(1,2)
(3,3)
(6,4)
(10,5)
res15: Int = 15

简化写法

scala> Array(1,2,3,4,5).fold(0)(_+_)
res16: Int = 15

函数变种
\quad \quad fold函数也有两个函数变种,分别是foldLeft和foldRight。

  • foldLeft:指的是op函数按集合中元素的顺序从左到右对其进行reduce操作,且得到的结果放在左边,数组下一个元素放在右边。等价于reduce函数
  • foldRight:指的是op函数按集合中元素的顺序从右到左对其进行reduce操作,且得到的结果放在右边,数组下一个元素放在左边。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值