首页 > 其他分享 >Scala 第二篇 算子篇

Scala 第二篇 算子篇

时间:2024-07-23 11:28:03浏览次数:18  
标签:val Scala buffer ArrayBuffer 元素 Int 算子 println 第二篇

一、数组方法

1、数组的遍历
val array = Array(1, 2, 3, 4, 5)

val indices: Range = array.indices		// 提取下标区间
for (i <- indices) {
    println(array(i))					// 根据下标提取元素,注意是小括号
}

for (i <- 0 until array.length) {		// 使用 until 遍历数组下标
  println(array(i))
}

array.foreach(println)					// 使用 foreach 遍历数组元素

val iter = array.iterator			// 正向迭代器
val reIter = array.reverseIterator	// 逆向迭代器
while (iter.hasNext) {
  println(iter.next())
}
2、数组获取元素
        1、获取首尾元素
val buffer = ArrayBuffer(1, 2, 3, 4)

val head = buffer.head            // 第一个元素
val opt1 = buffer.headOption      // 第一个元素
val tail = buffer.tail            // 除第一个元素以外的其他元素
// 剩余元素(阶梯) 4(1,2,3,4),3(2,3,4),2(3,4),1(4),0()
val tails: Iterator[ArrayBuffer[Int]] = buffer.tails

val last = buffer.last            // 最后一个元素
val opt2 = buffer.lastOption      // 最后一个元素
val init = buffer.init    // 除最后一个元素以外的其他元素
val inits = buffer.inits  // 剩余元素(阶梯) 4(1,2,3,4),3(1,2,3),2(1,2),1(1),0()
      2. 获取满足条件连续长度和元素
val size1 = buffer.prefixLength(e => e < 3)     // 从集合的开头满足条件元素数量
val size2 = buffer.segmentLength(e => e > 1, 1) //从 from 下标的连续满足条件元素数量

val buf1 = buffer.take(1)         // 从集合的开头开始获取指定数量的元素。
val buf2 = buffer.takeRight(2)    // 从集合的末尾开始获取指定数量的元素。
val buf3 = buffer.takeWhile(e => e < 3)  // 从集合的开头开始获取连续满足条件的元素。
3、数组排序
1、sortedsortBysortWith
val buffer = ArrayBuffer((5, 2), (2, 5), (3, 2), (2, 4))

val sort1 = buffer.sorted           // 默认按第一个值升序,如果第一个值相等按第二个值升序,如果有第三个值同理

val sort2 = buffer.sortBy(_._2)     // 指定排序值,按第二个值排序(默认升序)

// sortWith 定义元素之间的比较规则
// 如果第一个值不相等按第一个值降序,否则按第二个值降序
val sort3 = buffer.sortWith((a, b) => (
    if(a._1 != b._1) a._1 > b._1
    else a._2 > b._2
))
2、隐式函数 (不建议)
val buffer = ArrayBuffer((5, 2), (2, 5), (3, 2), (2, 4))
implicit val orderingTp2: Ordering[(Int, Int)] = Ordering.by(_._2) // 按第二个值
val sort5 = buffer.sorted          // 按第二个值升序
4、交集,并集,补集
// 结果类型:前(左)置确定

val buffer = ArrayBuffer(1, 2, 3, 4, 5)
val seq = Seq(3, 4, 5, 6, 7)

// 交集
val intersect: ArrayBuffer[Int] = buffer.intersect(seq)
println("交集:" + intersect.mkString(", "))

// 并集
val union: ArrayBuffer[Int] = buffer.union(seq)
println("并集:" + union.mkString(", "))

// 差集
val diff: ArrayBuffer[Int] = buffer.diff(seq)
println("差集:" + diff.mkString(", "))

输出:

交集:3, 4, 5
并集:1, 2, 3, 4, 5, 3, 4, 5, 6, 7
差集:1, 2

 补充:

// 连接字符串
val str0: String = buffer.mkString
val str1: String = buffer.mkString(sep:String)		// 指定分割符
val str2: String = buffer.mkString(start:String,sep:String,end:String)	// 指定,连接字符串的起始部分,分隔符,结束部分
5、集合转换操作
        1、一个维度的转变
import scala.collection.mutable.ArrayBuffer

val buffer = ArrayBuffer(1, 2, 3, 4, 5)
// 正向差异类型转变,(将数字x映射为x*2并转化为字符串)
val doubledBuffer: ArrayBuffer[String] = buffer.map(x => (x * 2).toString)
// 正向同类型转变
val squaredBuffer: ArrayBuffer[Int] = buffer.transform(x => x * x)
// 逆向转变
val reversedSquaredBuffer: ArrayBuffer[Int] = buffer.reverseMap(x => x * x)
        2、二维变换
import scala.collection.mutable.ArrayBuffer

val buffer2D = ArrayBuffer(
    ArrayBuffer(1, 2, 3),
    ArrayBuffer(4, 5, 6),
    ArrayBuffer(7, 8, 9)
)
// 使用 flatMap 将二维转换为一维,并对值做映射 (*2)
val flatBuffer: ArrayBuffer[Int] = buffer2D.flatMap(_.map(_ * 2))
// 使用 flatten 将二维转换为一维
val flattenedBuffer: ArrayBuffer[Int] = buffer2D.flatten
// 使用 transpose 进行二维数组缓冲区转置
val transpose: ArrayBuffer[ArrayBuffer[Int]] = buffer2D.transpose

        3、类型变换

import scala.collection.mutable
import scala.collection.parallel.mutable.ParArray

val buffer = mutable.Buffer(1, 2, 2, 3, 4, 5)
val buffer_tp2 = mutable.Buffer((1, "a"), (2, "b"), (3, "c"))

val mutableBuffer: mutable.Buffer[Int] = buffer.toBuffer // 转换为可变的,为了增删
val array: Array[Int] = buffer.toArray                   // 转换为数组,(下标,排序)
val parArray: ParArray[Int] = buffer.toParArray          // 转换为并行数组,分布式计算
val map: Map[Int, String] = buffer_tp2.toMap             // 转换为 Map,键值映射
val set: Set[Int] = buffer.toSet                         // 转换为集合(去重)
6、合并,拆解,填充 
import scala.collection.mutable.ArrayBuffer

val buffer1 = ArrayBuffer('a', 'b', 'c', 'd')
val buffer2 = ArrayBuffer(1, 2, 3)

// 最短原则合并,结果:(a,1), (b,2), (c,3)
val zippedShortest: ArrayBuffer[(Char, Int)] = buffer1.zip(buffer2)
// 最长原则合并,长度不够填充默认值,结果:(a,1), (b,2), (c,3), (d,0)
val zippedAll: ArrayBuffer[(Char, Int)] = buffer1.zipAll(buffer2, 'x', 0)
// 带索引合并
val zippedWithIndex: ArrayBuffer[(Char, Int)] = buffer1.zipWithIndex
// 拆解操作,拆解二元组,拆解三元组为unzip3
val (unzipped1, unzipped2): (ArrayBuffer[Char], ArrayBuffer[Int]) = zippedShortest.unzip
// 填充操作,不足6为填充: '_'
val paddedBuffer: ArrayBuffer[Char] = buffer1.padTo(6, '_')

// 输出结果
println("最短原则合并:" + zippedShortest)
println("最长原则合并:" + zippedAll)
println("带索引合并:" + zippedWithIndex)
println("拆解结果:" + unzipped1 + ", " + unzipped2)
println("填充后的数组:" + paddedBuffer)

 输出:

 最短原则合并:ArrayBuffer((a,1), (b,2), (c,3))
最长原则合并:ArrayBuffer((a,1), (b,2), (c,3), (d,0))
带索引合并:ArrayBuffer((a,0), (b,1), (c,2), (d,3))
拆解结果:ArrayBuffer(a, b, c), ArrayBuffer(1, 2, 3)
填充后的数组:ArrayBuffer(a, b, c, d, _, _)

7、分组,排列
import scala.collection.mutable.ArrayBuffer                                                      
                                                                                                 
val buffer = ArrayBuffer(1, 2, 3, 4, 5)                                                          
                                                           
// 切片操作,提取下标为1开始4结束的元素(包头不包尾)                                                                 
val bufferSlice: ArrayBuffer[Int] = buffer.slice(1, 4)
// 滑动窗口操作,固定大小为 2 的滑动窗口,并且每次滑动 1 个元素。
val itAB: Iterator[ArrayBuffer[Int]] = buffer.sliding(2, 1)  //                                    
// 分组操作                                                                                          
val itGrouped: Iterator[ArrayBuffer[Int]] = buffer.grouped(2)	// 定长分组
val map: Map[Int, ArrayBuffer[Int]] = buffer.groupBy(_ % 2) 	// 按键分组
val tp2: (ArrayBuffer[Int], ArrayBuffer[Int]) = buffer.partition(_ < 4)	// 2 分区,按要求(小于4)分为两类
val splits: (ArrayBuffer[Int], ArrayBuffer[Int]) = buffer.splitAt(2)	// 2 分区,在索引位置2处分成两部分
// grouped(size) <=> sliding(size,size),两者等价

val itPermutations: Iterator[ArrayBuffer[Int]] = buffer.permutations	// 全排列  
val itCombinations: Iterator[ArrayBuffer[Int]] = buffer.combinations(2) // 组合排列

二、算子

1、简单计算
        1、数组元素为数值类型可以直接计算
import scala.collection.mutable.ArrayBuffer
val buffer = ArrayBuffer(1, 2, 3, 4, 5)
val sum = buffer.sum
val max = buffer.max
val min = buffer.min
val pro = buffer.product	// 阶乘
        2、非数值元素类型
val buffer = ArrayBuffer(("aaa", 3), ("bbb", 1), ("ccc", 2), ("aaa", 2))
val sum = buffer2.map(e => e._2).sum
val max: (String, Int) = buffer2.maxBy(e => e._2)
val min: (String, Int) = buffer2.minBy(e => e._2)
val cnt = buffer2.count(e => e._2 < 2)
        3、计算优化:并行序列,并行计算

并行数组 ParArray[T],它是一个并行版本的数组,允许在多个线程上并行地操作数组元素。这对于对大型数据集进行处理或利用多核处理器进行并行计算非常有用,可以提高处理效率。

val par: ParArray[T] = buffer.par
 2、高阶计算
        1、简介
  • 聚合操作
  • aggregate 方法对数组进行聚合操作,指定一个初始值 o: O,一个用于映射元素的函数 map: (O, T) => O,和一个用于合并两个结果的函数 red: (O, O) => O。这个操作会将数组元素映射为结果。在并行计算中使用这个操作,直接调用并行数组的 par.aggregate 方法。

  • 折叠操作:

  • fold 方法对数组进行折叠,指定一个初始值 init: O,和一个用于合并两个结果的函数 func: (O, O) => O。这个操作会从数组的一端开始,逐个将元素与初始值进行合并,直到折叠到另一端。通过指定 Left 或 Right 来指定折叠的方向。
  • 扫描操作
  • scan 方法对数组进行扫描,指定一个初始值 init: O,和一个用于合并两个结果的函数 f: (O, O) => O。这个操作会从数组的一端开始,逐个将元素与初始值进行合并,并在每一步生成一个过程结果。最终结果是一个包含所有过程结果的数组缓冲区。
  • 归约操作
  • reduce 方法对数组进行归约操作,指定一个用于合并两个结果的函数 f: (O, O) => O。这个操作会从数组的一端开始,逐个将元素进行合并,直到最终只剩下一个结果为止。通过指定 Left 或 Right 来指定归约的方向。
// 聚合操作
val rst:O = buffer.aggregate(o:O)(map:(O,T)=>O,red:(O,O)=>O)
val rst:O = par.aggregate(o:O)(map:(O,T)=>O,red:(O,O)=>O)		// 并行 Map & Red
// 双向折叠操作
val rst:O = buffer.fold[Left|Right](init:O)(func:(O,O)=>O)
// 过程结果扫描操作
val rst:ArrayBuffer[O] = buffer.scan[Left|Right](init:O)(f:(O,O)=>O)
// 归约操作
val rst:O = buffer.reduce[Left|Right](f:(O,O)=>O)
 2、案例
        1、aggregate 案例
val buffer = ArrayBuffer(1, 2, 3, 4)

val map = (a:Int,b:Int) => {
	println(s"MAP $a + $b = ${a+b}")
	a + b
}
val reduce = (a:Int,b:Int) => {
    println(s"RED $a + $b = ${a+b}")
	a + b
}
val rst: Int = buffer.par.aggregate(0)(map,reduce)

        输出:

MAP 0 + 2 = 2
MAP 0 + 1 = 1
MAP 0 + 4 = 4
MAP 0 + 3 = 3
RED 1 + 2 = 3
RED 3 + 4 = 7
RED 3 + 7 = 10

         2、fold 案例
val buffer = ArrayBuffer(1, 2, 3)
val add = (a:Int, b:Int) => {
    println(s"$a + $b = ${a+b}")
    a + b
}
val rst: Int = buffer.fold(0)(add)
println("-------------------------")
val rst: Int = buffer.foldRight(0)(add)

输出:

0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
-------------------------
3 + 0 = 3
2 + 3 = 5
1 + 5 = 6

         3、scan 案例
val buffer = ArrayBuffer(1, 2, 3, 4)
val add = (a: Int, b: Int) => {
    println(s"$a + $b = ${a + b}")
    a + b
}
val rst1: ArrayBuffer[Int] = buffer.scan(0)(add)
println(rst1)

val rst2: ArrayBuffer[Int] = buffer.scanRight(0)(add)
println(rst2)

 输出:

 0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
ArrayBuffer(0, 1, 3, 6, 10)
4 + 0 = 4
3 + 4 = 7
2 + 7 = 9
1 + 9 = 10
ArrayBuffer(10, 9, 7, 4, 0)

         4、reduce 案例
val buffer = ArrayBuffer(1, 2, 3, 4)
val add = (a: Int, b: Int) => {
    println(s"$a + $b = ${a + b}")
    a + b
}
val rst1: Int = buffer.reduce(add)
println("-------------------------")
val rst2: Int = buffer.reduceRight(add)

 输出:

1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
-------------------------
3 + 4 = 7
2 + 7 = 9
1 + 9 = 10

 3、简单优化
  1. sizeHint(size: Int):这个重载形式接收一个整数参数 size,表示预期添加的元素数量。调用这个方法后,缓冲区的实现可能会调整内部数据结构的大小以适应更大的元素数量,从而提高性能。这对于在添加大量元素之前知道预期大小的情况很有用。
  2. sizeHint(data: TraversableLike[T]):这个重载形式接收一个 TraversableLike[T] 类型的参数 data,表示另一个集合,它的大小可以作为预期添加的元素数量的提示。调用这个方法后,缓冲区的实现可能会根据给定集合的大小来调整内部数据结构的大小,以适应更大的元素数量。

  3. sizeHintBounded(size: Int, data: TraversableLike[T]):这个重载形式接收两个参数:一个整数 size 和一个 TraversableLike[T] 类型的参数 data。它表示给定集合的大小和另一个预期添加的元素数量。调用这个方法后,缓冲区的实现可能会根据这两个参数来调整内部数据结构的大小,以适应更大的元素数量。

// 给出预期添加元素数量的提示,用于优化构建器的性能
buffer.sizeHint(size:Int)
buffer.sizeHint(data:TraversableLike[T])
buffer.sizeHintBounded(size:int,data:TraversableLike[T])

标签:val,Scala,buffer,ArrayBuffer,元素,Int,算子,println,第二篇
From: https://blog.csdn.net/2301_79349971/article/details/140604837

相关文章

  • 01-Scala开发环境搭建
    Scala开发环境搭建1.安装JDK:https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html2.IDEA安装Scala插件3.添加Scala的全局的Libraries4.打印HelloWorldTips:Scala中为什么要在object中才能使用Main方法?Scala中将“静态”与“类”区分的......
  • 如何从 Oracle 迁移到 Greenplum 第二篇
    如何从Oracle迁移到Greenplum第二篇Greenplum中文社区Greenplum中文社区2020/04/3009:00阅读数2.7K本文被收录于专区数据库进入专区参与更多专题讨论  在上周和大家分享的《如何从Oracle迁移到Greenplum第一篇》中,我们介绍了Greenplum......
  • Python爬虫教程第二篇:进阶技巧与实战案例
    Python爬虫教程第二篇:进阶技巧与实战案例在上一篇教程中,我们学习了Python爬虫的基础概念、基本流程以及一个简单的入门实践案例。本篇教程将带领大家进一步探索Python爬虫的进阶技巧,并提供一个实战案例,帮助大家提升爬虫技能。一、进阶技巧处理JavaScript渲染的页面在We......
  • Spark算子综合案例 - Scala篇
    文章目录第1关:WordCount-词频统计代码第1关:WordCount-词频统计任务描述本关任务:使用SparkCore知识编写一个词频统计程序。编程要求请仔细阅读右侧代码,根据方法内的提示,在Begin-End区域内进行代码补充,具体任务如下:对文本文件内的每个单词都统计出其出......
  • 从新手到高手:Scala函数式编程完全指南,Scala 方法与函数(10)
    1、Scala方法与函数Scala有方法与函数,二者在语义上的区别很小。Scala方法是类的一部分,而函数是一个对象可以赋值给一个变量。换句话来说在类中定义的函数即是方法。Scala中的方法跟Java的类似,方法是组成类的一部分。Scala中的函数则是一个完整的对象,Scala中的函......
  • 【读书笔记】《深度神经网络FPGA设计与实现》(孙其功)第三章 深度神经网络基础层算子介
    深度神经网络基础层算子介绍1.卷积算子2.反卷积算子3.池化算子(1)平均池化算子:(2)最大池化算子:4.激活算子5.全连接算子6.Softmax算子7.批标准化算子8.Shortcut算子1.卷积算子基础概念(1)卷积核(Kernel)。图像处理时,对输入图像中一个小区域像素加权......
  • Linux设备驱动器 之二 线程同步第二篇
    Linux设备驱动器之二线程同步第二篇mutex数据结构LinuxAPIs在Linux驱动器中的应用NXPfreescale系列QSPI驱动器变量定义初始化存取数据semaphore数据结构LinuxAPIs在Linux驱动器中的应用ELAN的Uxxx系列驱动器变量定义初始化同步操作mutex数据结构stru......
  • 华为昇腾训练营笔记-Ascend C算子开发
     一、核函数开发核函数(KernelFunction)是AscendC算子设备侧实现的入口。在核函数中,需要为在一个核上执行的代码规定要进行的数据访问和计算操作,当核函数被调用时,多个核都执行相同的核函数代码,具有相同的参数,并行执行。 核函数的定义为:extern"C"__global____aicore__vo......
  • Scala入门
    ScalaScala特点:和Java无缝整合,满足各自语法基础上调用Java库;类型推断,类似于Golang,Scala通过val声明常量,通过var声明变量。支持并行和分布式;高阶函数编程,可以理解为面向对象编程,但是函数可以作为对象并当作参数传入。数据类型Null:代表空值,是AnyRef的子类;No......
  • Scala的基础知识点
    scala特点Scala介绍Scala是把函数式编程思想和面向对象编程思想结合的一种编程语言大数据计算引擎Spark由Scala编写Scala特点多范式面向对象函数式编程兼容JAVA类库调用互操作语法简洁代码行短类型推断抽象控制静态类型化可检验安全重构支持并发......