Collections
Vector
If the length of a vector is smaller or equal than 32, it's an array. If not, it's an array of arrays, and each sub-array has the length of 32.
Once a sub-array is changed (created a new one to replace the old one), all its parents need to be changed, too.
Operations on Vector
val nums = Vector(1, 2, -3)
val people = Vector("Bob", "Peter")
Vector doesn't support ::
operator. Instead, it supports:
x +: xs
: add the elementx
at the front ofxs
xs :+ x
: add the elementx
at the end ofxs
Hierarchy
Iterable
/ | |
Seq Set Map
/ \
List Vector
Array and String
Array
and String
are classes in Java, they are not the subclass of Seq
. But they support the same operators as Seq
.
val xs: Array[Int] = Array(1, 2, 3)
xs.map(x => x * 2)
val ys: String = "Hello"
ys.filter(_.isUpper)
Ranges
It's a subclass of Seq
.
val r: Range = 1 until 3 // 1, 2
val s: Range = 1 to 3 // 1, 2, 3
1 until 10 by 2
6 to 1 by -1
More operations
-
zip
val a = List(1, 2, 3) val b = List("a", "b") a.zip(b) // List((1, "a"), (2, "b"))
-
flatMap
It takes a function
f
that returns itself a collection, and applyf
to each element, and then concatenate all the results.val a = List(1, 2, 3) val toPair = (element: Int) => List(element, element + 1) a.flatMap(toPair) // List(1, 2, 2, 3, 3, 4)
We can combine the operations.
val chars = List('a', 'b', 'c')
val numbers = List(1, 2, 3)
val combinations = chars.flatMap(c => numbers.map(n => s"$c$n"))
// List(a1, a2, a3, b1, b2, b3, c1, c2, c3))
3 ways to implement Scalar Product
def scalarProduct(xs: Vector[Int], ys: Vector[Int]): Int = {
xs.zip(ys).map(xy => xy._1 * xy._2).sum
}
The element in the list returned by zip
is a tuple
. Therefore, we have other way.
def scalarProduct(xs: Vector[Int], ys: Vector[Int]): Int = {
xs.zip(ys).map((x, y) => x * y).sum
}
Note that there's some automatic decomposition going on here. xs.zip(ys)
gives a list of pairs.
Map takes a pair, but here the lambda with parts to the map is a function of two parameters.
Behind the scenes, the compiler will automatically decompose the pair and put the first half in x
and the second half in y
.
To be more elegant, we can use _
.
def scalarProduct(xs: Vector[Int], ys: Vector[Int]): Int = {
xs.zip(ys).map(_ * _).sum
}