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