Scala集合常用函数 - 高级计算函数

水善利万物而不争,处众人之所恶,故几于道💦

目录

[  1. 过滤 - filter](#  1. 过滤 - filter)
[  2. 转换/映射 - map](#  2. 转换/映射 - map)
[  3. 扁平化 - flatten](#  3. 扁平化 - flatten)
[  4. 扁平化+映射 - flatMap](#  4. 扁平化+映射 - flatMap)
[  5. 分组 - groupBy](#  5. 分组 - groupBy)
[  6. 简化(规约) - reduce](#  6. 简化(规约) - reduce)
[  7. 折叠 - fold](#  7. 折叠 - fold)
[  8. 函数小练习](#  8. 函数小练习)

1. 过滤 - filter

 遍历一个集合并从中获取满足指定条件的元素组成一个新的集合

scala 复制代码
//对List集合进行遍历,将偶数取出,放到新的集合中去

val list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9)

println(list.filter((a: Int) => {a % 2 == 0}))

println(list.filter(_ % 2 == 0))

  filter()方法的参数是一个函数类型,其返回值为布尔类型,函数体指明过滤的规则。

2. 转换/映射 - map

 将集合中的每一个元素映射到某一个函数

scala 复制代码
//将集合中的元素进行乘2操作
println(list.map(_ * 2))

3. 扁平化 - flatten

flatten函数用于将嵌套的集合展平为一个单层的集合。它将嵌套的集合中的元素取出来,放入一个新的集合中。

flatten函数只对嵌套的集合有效,如果集合中的元素不是集合类型,则flatten函数不会有任何效果

注意: :::操作符用于连接两个集合,它将两个集合合并成一个新的集合。它接受右侧的集合作为参数,并将其添加到左侧的集合之后。而flatten函数用于将嵌套的集合展平为一个单层的集合。它们的功能和用途是不同的

scala 复制代码
val list1 = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
val newList1: List[Int] = list1.flatten
println(newList1)

结果:
List(1, 2, 3, 4, 5, 6, 7, 8, 9)

4. 扁平化+映射 - flatMap

flatMap相当于先进行map操作,再进行flatten操作

scala 复制代码
val strings = List("hello atguigu", "hello jingjing", "qcln jingjing")

//常规实现
val stringses: List[Array[String]] = strings.map(_.split(" "))
println(stringses.flatten)

// 使用flatMap函数实现
val strings2: List[String] = strings.flatMap(_.split(" "))
println(strings2)

5. 分组 - groupBy

 按照指定的规则对集合的元素进行分组

scala 复制代码
val nameList = List("jingjing", "banzhang", "banhua", "anqcln", "jinghua")

// 按元素首字母进行分组
val charToStrings: Map[Char, List[String]] = nameList.groupBy(_.charAt(0))
println(charToStrings)

结果:
Map(b -> List(banzhang, banhua), j -> List(jingjing, jinghua), a -> List(anqcln))

进阶:修改分组后key的值

  直接再进行一次map映射

scala 复制代码
// 将分组后key的值改为大写
val keyStyle1: immutable.Iterable[String] = charToStrings.map(MapKv => {
      val upperKey: Char = MapKv._1.toUpper
      upperKey + " -- " + MapKv._2
    })
println(keyStyle1)

// 将分组后key为b的值改为X
val keyStyle2: immutable.Iterable[String] = charToStrings.map(MapKV => {
  val newKey = if (MapKV._1.equals('b')) 'X' else MapKV._1
  newKey + " -- " + MapKV._2
})
println(keyStyle2)

  说明:Scala中if条件判断其实是有返回值的,返回值取决于满足条件的代码体的最后一行内容。

6. 简化(规约) - reduce

 通过指定的逻辑将集合中的数据进行聚合,从而减少数据,最终获取结果

reduce:底层调用的是reduceLeft。他要求传入的两个参数的类型必须一致,返回值也是该类型。

reduceLeft:传入的两个参数的参数类型可以不一致。它从集合左边开始做聚合,返回值类型是左边的类型。

reduceRight:传入的两个参数的参数类型可以不一致。它从集合右边开始做聚合,返回值类型是右边的类型。

scala 复制代码
val list = List(1, 2, 3, 4)

val res: Int = list.reduce(_ + _)
val res: Int = list.reduceLeft(_ + _)
val res: Int = list.reduceRight(_ + _)
println(res)

println(list.reduceLeft(_ - _))  // -8
println(list.reduceRight(_ - _))  // -2

val list2: List[Int] = List(3, 4, 5, 8, 10)
println(list2.reduceRight(_ - _))   // 6

reduceLeft:从左边开始简化,用第一个元素减去第二个元素,然后再用结果减去第三个元素

reduceRight:从右边开始简化,用倒数第二个元素减去倒数第一个元素,再用倒数第三个元素减去上一个结果

从源码角度理解reduceRight的计算方法

7. 折叠 - fold

 简化的一种特殊情况,它是集合外元素和集合内部元素进行聚合。计算方式和简化相似。

scala 复制代码
val list2: List[Int] = List(3, 4, 5, 8, 10)  

println(list2.fold(10)(_+_))  // 40

println(list2.foldLeft(11)(_ - _))  // -19

println(list2.foldRight(12)(_ - _))   // -6

foldLeft:从左边开始折叠,用集合外的元素减去集合左边第一个元素,再用结果减去第二个元素,以此类推

foldRight:从右边开始折叠,用集合最后一个元素减去集合外的元素,再用集合倒数第二个元素减去结果,以此类推


8. 函数小练习

将两个map集合中的数据合并(key相同的话,value相加)

scala 复制代码
val map1 = mutable.Map("a"->1, "b"->2, "c"->3)
val map2 = mutable.Map("a"->4, "b"->5, "d"->6)


//方法一   
// map1("e") = 9 这样也能添加元素....
val res: mutable.Map[String, Int] = map1.foldLeft(map2)(
  // m2Jh表示map2,m1表示map1中的每一个元素
  (m2Jh, m1) => {
    // 指定合并的规则
    val m1Key: String = m1._1
    val m1Value: Int = m1._2
    // 根据map1中元素的key更新map2中的value,或者直接添加
    m2Jh(m1Key) = m2Jh.getOrElse(m1Key, 0) + m1Value 
    m2Jh
  })

//  ================================== 方法二 ================================= 
// 我写的,通俗易懂
val res: mutable.Map[String, Int] = map1.foldLeft(map2)((m2Jh, m1) => {
  val m1Key: String = m1._1
  val m1Value: Int = m1._2

  // 在map2中获取value,如果获取到,执行update更新value,如果获取不到执行put添加
  val flag: Int = m2Jh.getOrElse(m1Key, 0)  
  if(flag==0){
    m2Jh.put(m1Key,m1Value)
  }else{
    m2Jh.update(m1Key,m1Value+flag)
  }
  m2Jh  // 将map2集合返回,因为foldLeft()()的参数类型就要求的
})

println(res)

分析:

  两个集合合并,涉及到两个集合,用折叠fold

  折叠有三个,具体选哪个,fold要求集合外部元素类型和集合内部元素类型一致,foldLeftfoldRight可以不一致,这两个集合合并的话,明显类型不一致,因为方法调用的时候把其中一个map集合整体作为参数传了进去,这个参数类型是map,而方法调用者是一个map集合,内部元素的类型是一个元组,这一个元组,一个map类型明显不一致,所以不能用fold,那就用foldLeft得了,简单。

  最后合并的思路是什么? 把其中一个map集合作为参数传递进去,然后再迭代另一个集合的时候取到key和value判断,如果这个key在集合中存在,那么更新它的value,如果这个key在集合中不存在,将这个key和value加入到这个集合中。

相关推荐
Thomas21431 天前
Java scala 数组 链表
java·链表·scala
江畔柳前堤3 天前
消息队列:从直觉到精通的完整认知地图
开发语言·人工智能·算法·机器学习·ruby on rails·scala
2601_949950639 天前
用练题簿小程序把课件做成可以在线刷题的内容
小程序·练习·小程序推荐
hopsky17 天前
《Scala 学习手册》核心内容详解
人工智能·学习·scala
abcy0712131 个月前
scala playframework 搭建与新建controller教程
scala
lpfasd1231 个月前
编程语言榜单变迁分析
开发语言·后端·scala
戮漠summer2 个月前
Missing Semester 计算机教育中缺失的一课 Lecture 01 Shell
开发语言·后端·scala
醉熏的石头2 个月前
Ubuntu 中的编程语言(中)
linux·ubuntu·scala
Irene19912 个月前
Scala、Java、Python、JavaScript 的核心特性和应用场景(Python 的“单机“局限性:GIL 机制导致的多核并行缺陷)
java·javascript·python·scala
DogDaoDao3 个月前
【第 05 篇】Python的字典与集合
开发语言·python·集合·字典