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

news/2025/1/16 5:57:30/

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

目录

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

1. 过滤 - filter

 遍历一个集合并从中获取满足指定条件的元素组成一个新的集合
//对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

 将集合中的每一个元素映射到某一个函数
//将集合中的元素进行乘2操作
println(list.map(_ * 2))

3. 扁平化 - flatten

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

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

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

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操作
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

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

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映射

// 将分组后key的值改为大写
val keyStyle1: immutable.Iterable[String] = charToStrings.map(MapKv => {val upperKey: Char = MapKv._1.toUpperupperKey + " -- " + 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._1newKey + " -- " + MapKV._2
})
println(keyStyle2)

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

6. 简化(规约) - reduce

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

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

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

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

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(_ - _))  // -2val list2: List[Int] = List(3, 4, 5, 8, 10)
println(list2.reduceRight(_ - _))   // 6

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

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

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

7. 折叠 - fold

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

val list2: List[Int] = List(3, 4, 5, 8, 10)  println(list2.fold(10)(_+_))  // 40println(list2.foldLeft(11)(_ - _))  // -19println(list2.foldRight(12)(_ - _))   // -6

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

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


8. 函数小练习

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

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._1val 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._1val 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加入到这个集合中。


http://www.ppmy.cn/news/943126.html

相关文章

基于Java+SpringBoot+Vue前后端分离校园管理系统详细设计和实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

ffdshow 源代码分析1 : 整体结构

ffdshow是一个非常强大的DirectShow解码器,封装了ffmpeg,libmpeg2等解码库。它也提供了丰富的加工处理选项,可以锐化画面,调节画面的亮度等等。不止是视频,FFDShow现在同样可以解码音频,AC3、MP3等音频格式…

[总结]FFMPEG视音频编解码零基础学习方法

在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者。在和大家探讨的过程中,我忽然发现了一个问题:在“大神”…

H.264开源解码器评测

H.264开源解码器评测 Peter Lee 2006.05.07 videosky.9126.com 2003年5月,当H.264编码标准草案发布时,很多人都觉得H.264太复杂,不宜实用。眨眼间3年过去了,以往的论断、疑惑被如今的现实冲洗的干干净净。随着硬件性能的提高和视频…

ffdshow

ffdshow ffdshow是一套免费的编解码

H.264/AVC 的各大主流编解码器

在这篇文章里,我们将介绍在H.264编解码标准的基础上,实现的各主流编解码器。我们前面曾多次提到,H.264只是一个编解码的标准协议,它同MPEG-1和MPEG-2一样,协议里并没有规定编解码器的具体结构和实现方法。但是要求生成…

ffdshow 源代码分析 6: 对解码器的dll的封装(libavcodec)

ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog) ffdshow 源代码分析 3: 位图覆盖滤镜(设置部分Settings&#xff0…

ffdshow 源代码分析 9: 编解码器有关类的总结

ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffdshow 源代码分析 2: 位图覆盖滤镜(对话框部分Dialog) ffdshow 源代码分析 3: 位图覆盖滤镜(设置部分Settings&#xff0…