Array
Array,长度不可改变的数组,Scala数组的底层实际上是Java数组,如字符串数组在底层就是Java的String[],整数数组在底层就是Java的Int[]。
1// 数组初始化后,长度就固定下来了,而且元素全部根据其类型初始化
2scala> val a = new Array[Int](10)
3a: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
4scala> a(0)=1
5scala> a
6res7: Array[Int] = Array(1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
7scala> a(0)
8res8: Int = 1
9scala> val a = new Array[String](10)
10a: Array[String] = Array(null, null, null, null, null, null, null, null, null, null)
11scala> a(1)="leo"
12scala> a
13res10: Array[String] = Array(null, leo, null, null, null, null, null, null, null, null)
1// 可以直接使用Array()创建数组,元素类型自动推断
2scala> val a = Array("hello", "world")
3a: Array[String] = Array(hello, world)
4scala> a(0)
5res12: String = hello
6scala> a(0) = "hi"
7scala> a
8res14: Array[String] = Array(hi, world)
9scala> val a = Array("leo", 30)
10a: Array[Any] = Array(leo, 30)
ArrayBuffer
在Scala中,如果需要类似于Java中的ArrayList这种长度可变的集合类,可以使用ArrayBuffer。
1// 可以预先导入ArrayBuffer类
2scala> import scala.collection.mutable.ArrayBuffer
3import scala.collection.mutable.ArrayBuffer
4// 使用ArrayBuffer()的方式创建一个空的ArrayBuffer
5scala> val b = ArrayBuffer[Int]()
6b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
7// 使用+=操作符,可以添加一个元素,或者多个元素
8scala> b += 1
9res0: b.type = ArrayBuffer(1)
10scala> b += (2,3,4,5)
11res1: b.type = ArrayBuffer(1, 2, 3, 4, 5)
12// 使用++=操作符,可以添加其他集合中的所有元素
13scala> b ++= Array(6,7,8,9,10)
14res2: b.type = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
15// 从尾部截断指定个数的元素
16scala> b.trimEnd(5)
17scala> b
18res4: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5)
19// 在指定位置插入元素,插入操作效率很低,因为需要移动指定位置后的所有元素
20scala> b.insert(5,6)
21scala> b
22res6: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6)
23scala> b.insert(6,7,8,9,10)
24scala> b
25res8: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
26// remove()移除指定位置的元素
27scala> b.remove(1)
28res9: Int = 2
29scala> b
30res10: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 3, 4, 5, 6, 7, 8, 9, 10)
31scala> b.remove(1,3)
32scala> b
33res12: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 6, 7, 8, 9, 10)
34// Array与ArrayBuffer可以互相进行转换
35scala> val bArray = b.toArray()
36<console>:13: error: not enough arguments for method toArray: (implicit evidence$1: scala.reflect.ClassTag[B])Array[B].
37Unspecified value parameter evidence$1.
38 val bArray = b.toArray()
39 ^
40scala> val bArray = b.toArray
41bArray: Array[Int] = Array(1, 6, 7, 8, 9, 10)
42scala> val a = Array("hello", "world")
43a: Array[String] = Array(hello, world)
44scala> val aArrayBuffer = a.toBuffer
45aArrayBuffer: scala.collection.mutable.Buffer[String] = ArrayBuffer(hello, world)
46scala> aArrayBuffer += "hi"
47res13: aArrayBuffer.type = ArrayBuffer(hello, world, hi)
48scala> val a = aArrayBuffer.toArray
49a: Array[String] = Array(hello, world, hi)
遍历Array和ArrayBuffer
1// 使用for循环和until遍历,until是RichInt提供的函数
2scala> for(i <- 0 until b.length) print(b(i) + " ")
31 6 7 8 9 10
4// 跳跃遍历
5scala> for(i <- 0 until (b.length,2)) print(b(i) + " ")
61 7 9
7// 从尾部遍历
8scala> for(i <- (0 until b.length).reverse) print(b(i) + " ")
910 9 8 7 6 1
10// 增强for循环遍历
11scala> for(e <- b) print(e + " ")
121 6 7 8 9 10
数组常见操作
1scala> val a = Array(1,2,3,4,5)
2a: Array[Int] = Array(1, 2, 3, 4, 5)
3// 数组元素求和
4scala> val sum = a.sum
5sum: Int = 15
6// 获取数组最大值
7scala> val max = a.max
8max: Int = 5
9// 对数组进行排序
10scala> val a2 = Array(9,5,7,3,1,2)
11a2: Array[Int] = Array(9, 5, 7, 3, 1, 2)
12scala> scala.util.Sorting.quickSort(a2)
13// 获取数组中所有元素内容
14scala> a2
15res20: Array[Int] = Array(1, 2, 3, 5, 7, 9)
16scala> a.mkString
17res21: String = 12345
18scala> a.mkString(",")
19res22: String = 1,2,3,4,5
20scala> a.mkString("(", ",", ")")
21res23: String = (1,2,3,4,5)
22// toString函数
23scala> a.toString
24res24: String = [I@1bb8e50
25scala> val b = ArrayBuffer[Int]()
26b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
27scala> b += (1,2,3,4,5)
28res25: b.type = ArrayBuffer(1, 2, 3, 4, 5)
29scala> b.toString
30res26: String = ArrayBuffer(1, 2, 3, 4, 5)
31scala> b.mkString(",")
32res27: String = 1,2,3,4,5
数组转换
使用yield和函数式编程转换数组,
1// 对Array进行转换,获取的还是Array
2scala> val a = Array(1,2,3,4,5)
3a: Array[Int] = Array(1, 2, 3, 4, 5)
4scala> val a2 = for(ele <- a) yield ele *ele
5a2: Array[Int] = Array(1, 4, 9, 16, 25)
6// 对ArrayBuffer进行转换,获取的还是ArrayBuffer
7scala> val b = ArrayBuffer[Int]()
8b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
9scala> b += (1,2,3,4,5)
10res28: b.type = ArrayBuffer(1, 2, 3, 4, 5)
11scala> val b2 = for(ele <- b) yield ele *ele
12b2: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 4, 9, 16, 25)
13// 结合if守卫,仅转换需要的元素
14scala> val a3 = for(ele <- a if ele % 2 ==0) yield ele * ele
15a3: Array[Int] = Array(4, 16)
16// 使用函数式编程转换数组(通常使用第一种方式)
17scala> a.filter(_ % 2 == 0).map(_ * 2)
18res29: Array[Int] = Array(4, 8)
19scala> a.filter(_ % 2 == 0) map{_ * 2}
20res30: Array[Int] = Array(4, 8)
案例:移除第一个负数之后的所有负数
1scala> import scala.collection.mutable.ArrayBuffer
2import scala.collection.mutable.ArrayBuffer
3scala> val a = ArrayBuffer[Int]()
4a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
5scala> a += (1,2,3,4,5,-1,-3,-5,-9)
6res31: a.type = ArrayBuffer(1, 2, 3, 4, 5, -1, -3, -5, -9)
7scala> :paste
8// Entering paste mode (ctrl-D to finish)
9var foundFirstNegative = false
10var arrayLength = a.length
11var index = 0
12while(index < arrayLength) {
13 if(a(index)>=0) {
14 index += 1
15 } else {
16 if(!foundFirstNegative) { foundFirstNegative = true; index += 1}
17 else {a.remove(index); arrayLength -= 1}
18 }
19}
20// Exiting paste mode, now interpreting.
21foundFirstNegative: Boolean = true
22arrayLength: Int = 6
23index: Int = 6
24scala> a
25res33: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5, -1)
改良版,
1scala> val a = ArrayBuffer[Int]()
2a: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
3scala> a += (1,-1,2,-3,3,-5,4,-9,5)
4res34: a.type = ArrayBuffer(1, -1, 2, -3, 3, -5, 4, -9, 5)
5scala> :paste
6// Entering paste mode (ctrl-D to finish)
7var foundFirstNegative = false
8val keepIndexes = for(i <- 0 until a.length if !foundFirstNegative || a(i)>=0) yield {
9 if (a(i)<0) foundFirstNegative = true
10 i
11}
12for (i <- 0 until keepIndexes.length) {a(i) = a(keepIndexes(i))}
13a.trimEnd(a.length - keepIndexes.length)
14// Exiting paste mode, now interpreting.
15foundFirstNegative: Boolean = true
16keepIndexes: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 1, 2, 4, 6, 8)
17scala> a
18res36: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, -1, 2, 3, 4, 5)
本文首发于steem,感谢阅读,转载请注明。
微信公众号「数据分析」,分享数据科学家的自我修养,既然遇见,不如一起成长。
读者交流电报群
知识星球交流群