Scala学习笔记03_数组

in #cn7 years ago

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,感谢阅读,转载请注明。

https://steemit.com/@padluo


微信公众号「数据分析」,分享数据科学家的自我修养,既然遇见,不如一起成长。

数据分析


读者交流电报群

https://t.me/sspadluo


知识星球交流群

知识星球读者交流群