前言

Scala中的数组是一种非常重要的数据结构,它是用来存储同类型元素的容器,除此Scala还有其他存储数据的容器,例如元组、列表、映射等。在本期的内容分享中,我们将针对数组作基本的介绍,内容包含:

  • 数组的创建
  • 数组的操作
数组的创建

数组分定长数组和变长数组,定长数组是指在构建数组之前就确定了数组中所包含的元素个数,而变成数组则不确定数组的元素个数。所以变成数组的灵活性会显现地更强,可以实现数组的增、删、改的操作。

定长的一维数组
可以采用两种方式构建定长数组,分别是:

val array_name = Array(values)
val array_name = new Array[datatype](length)

采用第一种方法构建数组,可以设定数据类型,也可以不设定(因为Scala会根据传入的值进行类型推导),但使用第二种方法创建数组则必须指定具体的数据类型和元素个数。

举例

scala> val arr1 = Array(1,10,100,1000) // 直接构造有初始值的数组arr1: Array[Int] = Array(1, 10, 100, 1000)scala> val arr2 = new Array[String](3) // 构造3个长度的字符型数组arr2: Array[String] = Array(null, null, null)

对于arr2来说,在不指定具体的初始值情况下,Scala会根据指定的数据类型,设定对应的默认值,如字符型的默认值为null,整型的默认值为0,浮点型的默认值为0.0。如需给arr2数组重新赋值的话,可以使用索引方法(需要注意的是,数组的索引是利用一对圆括号)。

举例

// 通过索引技巧,往没有初始值的数组中添加值scala> arr2(0) = "Monday"scala> arr2(1) = "First"scala> arr2(2) = "No.1"scala> arr2res3: Array[String] = Array(Monday, First, No.1)

变长的一维数组
构造变长数组需要使用ArrayBuffer函数,但使用该函数之前,需要导入对应的模块,即

import scala.collection.mutable.ArrayBuffer

在构造变成的一维数组时,通常没有对应的初始值,其主要用于循环中的数据存储,不妨这里举一个简单的例子加以说明:

// 导入模块import scala.collection.mutable.ArrayBuffer// 创建对象object CreateVarArray {// 定义主函数  def main(args: Array[String]): Unit = {    val arr1 = Array(1,10,100,1000)    // 定义可变数组    val arr2 = ArrayBuffer[Double]()    for (i <- arr1) {      arr2 += math.log(i) // 类似于Python中列表的append方法    }    println("arr2 = " + arr2)  }}out:arr2 = ArrayBuffer(0.0, 2.302585092994046, 4.605170185988092, 6.907755278982137)

二维数组
二维数组的本质就是一个矩阵,由行和列构成,该类数组的构造需要使用ofDim函数,同样ofDim函数的使用也需要导入模块,即scala.Array模块。

举例

import scala.Array._object TwoDimArray {  def main(args: Array[String]): Unit = {    // 构造二维数组    val arr1 = ofDim[Int](3, 4)    // 往数组中写值    arr1(0)(0) = 1  ;  arr1(0)(1) = 10    arr1(0)(2) = 100  ;  arr1(0)(3) = 100    for (i <- 1 until 3) {      for (j <- 0 until 4){        arr1(i)(j) = (i + j) * 100      }    }    // 打印二维数组    println("arr1 =")    for (i <- 0 until 3){      for (j <- 0 until 4){        print(arr1(i)(j) + " ")      }      println()    }  }}out:arr1 =1 10 100 100 100 200 300 400 200 300 400 500
数组的操作

正如前文所说,数组是存储同一类型数据的容器,我们可以在容器的基础上对元素做一些基本的操作,包括数组元素的增、删、改、查、筛选、排序、排重等。但需要注意的是,由于定长数组的约束性较强,而导致其无法增加或删除元素。下面我们通过一些具体的实例加以说明。

数组元素的增操作
数组元素的增操作,只能针对变长数组,可以使用很多种方法,例如+=法,++=法,append法以及insert法。

举例

scala> var A2 = ArrayBuffer[String]()// 在变长数组A2中增加单个元素scala> A2 += "One"scala> println("A2 = " + A2)A2 = ArrayBuffer(One)// 在变长数组A2中增加多个元素scala> A2 ++= Array("Two","Three","Four")scala> println("A2 = " + A2)A2 = ArrayBuffer(One, Two, Three, Four)// 在变长数组A2中增加多个元素scala> A2.append("Five","Six")scala> println("A2 = " + A2)A2 = ArrayBuffer(One, Two, Three, Four, Five, Six)// 在指定位置增加元素scala> A2.insert(0,"ABC") // 在第一个位置增加scala> A2.insert(2,"张三","李四","王二","赵五") // 从第三个位置开始,增加四个元素scala> println("A2 = " + A2)A2 = ArrayBuffer(ABC, One, 张三, 李四, 王二, 赵五, Two, Three, Four, Five, Six)

数组元素的删操作
数组元素的删操作,同样也只能针对变长数组,可以使用很多种方法,例如remove法、trimStart法和trimEnd法。

举例

scala> A2.remove(0) // 删除一个元素scala> println("A2 = " + A2)A2 = ArrayBuffer(One, 张三, 李四, 王二, 赵五, Two, Three, Four, Five, Six)scala> A2.remove(5,2) // 从第6个元素开始,删除2个元素scala> println("A2 = " + A2)A2 = ArrayBuffer(One, 张三, 李四, 王二, 赵五, Four, Five, Six)scala> A2.trimEnd(2) // 删除末尾的两个元素scala> println("A2 = " + A2)A2 = ArrayBuffer(One, 张三, 李四, 王二, 赵五, Four)scala> A2.trimStart(2) // 删除开头的两个元素scala> println("A2 = " + A2)A2 = ArrayBuffer(李四, 王二, 赵五, Four)

数组元素的改操作
数组元素的改操作,既可以适用于定长数组,也可以适用于变长数组。修改元素的思想就是取而代之,即先通过索引的方式指定被修改的值,然后利用赋值的方式完成值的修改。

举例

scala> var A1 = Array(1,1,2,10,5,8,13)scala> A1(3) = 3 // 将定长数组A1的第四个元素改为3scala> println("A1 = " + A1.mkString(","))A1 = 1,1,2,3,5,8,13scala> A2(2) = "Hello" // 将变成数组A2的第三个元素修改为"Hello"scala> println("A2 = " + A2)A2 = ArrayBuffer(李四, 王二, Hello, Four)

在上面的代码中,我们使用了mkString方法,其功能是将可迭代对象的元素做拼接,并返回字符型的值,该方法可以指定元素拼接的连接符,如代码中的逗号。

数组元素的排重操作
可以利用数组的distinct方法实现元素的排重,但需要注意的是,排重操作并不能对数组产生变动,即不影响原始数组。
举例

scala> val A3 = Array(1,2,10,1,20,2,1,3,2,20)scala> val A3_Dupli = A3.distinct  // 必须将排重的结果重新赋值给新的变量scala> println("A3排重后的结果为:" + A3_Dupli.mkString(","))A3排重后的结果为:1,2,10,20,3

数组元素的排序操作
利用数组的sorted方法完成元素的排序,该方法默认为升序排序,如需降序还需要再使用reverse方法(即翻转)。同样,该方法无法改变原始数组。

scala> val A1_Sort = A1.sorted // 默认对数组A1作升序排序scala> println("A1升序后的结果为:" + A1_Sort.mkString(","))A1升序后的结果为:1,1,2,3,5,8,13scala> val A2_Sort = A2.sorted.reverse // 对数组A2作降序排序scala> println("A2降序后的结果为:" + A2_Sort)A2降序后的结果为:ArrayBuffer(王二, 李四, Hello, Four)

数组元素的统计操作
当数组的元素为数值类型时,我们可以对数组作一些基本的统计元素,如计数、求和、最小值、最大值等。
举例

scala> println("数组A1元素的总和为" + A1.sum)数组A1元素的总和为33scala> println("数组A2元素的最小值为" + A2.min)数组A2元素的最小值为Fourscala> println("数组A1元素的最大值为" + A1.max)数组A1元素的最大值为13scala> printf("数组A1中有%d个元素大于2\n", A1.count(x => x >2))数组A1中有4个元素大于2

数组元素的计算操作
除了可以对数组作统计运算,还可以做元素级别的运算,只需要借助foreach方法或map方法就可以轻松实现。需要注意的是,foreach方法没有返回值,但map方法是有返回值的。
举例

scala> print("每个数除于2.0的结果为:")scala> A1.foreach(x => print(" " + x/2.0))scala> println()每个数除于2.0的结果为: 0.5 0.5 1.0 1.5 2.5 4.0 6.5scala> println("每个数除于4.0的结果为:",A1.map(_/4.0).mkString(","))(每个数除于4.0的结果为:,0.25,0.25,0.5,0.75,1.25,2.0,3.25)

数组元素的筛选操作
尽管我们可以使用索引的方法,返回数组中的元素,但这样做的弊端在于必须知道所需元素的具体位置,如果数据量一旦很大,这种方法几乎行不通。所以接下来我们再介绍如何基于一个判断条件完成数组子元素的获取。
举例

scala> println("A1数组中所有大于2的元素为:",A1.filter(x => x >2).toList)(A1数组中所有大于2的元素为:,List(3, 5, 8, 13))
结语

本期的内容就介绍到这里,如果你有任何问题,欢迎在公众号的留言区域表达你的疑问。同时,也欢迎各位朋友继续转发与分享文中的内容,让更多的人学习和进步。

每天进步一点点:数据分析1480

大数据之脚踏实地学15--Scala的数组操作_数组元素