Constructing a Map
scala> val scores = Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8)// immutable scores: scala.collection.immutable.Map[String,Int] = Map(Alice -> 10, Bob -> 3, Cindy -> 8) scala> val scores = scala.collection.mutable.Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8)//mutable scores: scala.collection.mutable.Map[String,Int] = Map(Bob -> 3, Alice -> 10, Cindy -> 8) scala> val scores = new scala.collection.mutable.HashMap[String, Int]//a blank map scores: scala.collection.mutable.HashMap[String,Int] = Map()
The value of "Alice" -> 10 is ("Alice", 10). You could have equally well defined the map as
scala> val scores = Map(("Alice", 10), ("Bob", 3), ("Cindy", 8)) scores: scala.collection.immutable.Map[String,Int] = Map(Alice -> 10, Bob -> 3, Cindy -> 8)
Accessing Map Values
scala> val bobsScore = scores("Bob") bobsScore: Int = 3
To check whether there is a key with the given value, call the contains method:
scala> val bobsScore = if (scores.contains("Bob")) scores("Bob") else 0 bobsScore: Int = 3
or:
scala> val bobsScore = scores.getOrElse("Bob", 0) bobsScore: Int = 3
Updating Map Values
For a immutable Map:
scala> val newScores = scores + ("Bob" -> 10, "Fred" -> 7) newScores: scala.collection.immutable.Map[String,Int] = Map(Alice -> 10, Bob -> 10, Cindy -> 8, Fred -> 7)
scala>scores = scores - "Alice"
For an mutable Map:
scala> scores("Bob") = 10 scala> scores("Fred") = 7 // Adds a new key/value pair to scores scala> scores += ("Bob" -> 10, "Fred" -> 7) res11: scores.type = Map(Bob -> 10, Fred -> 7, Alice -> 10, Cindy -> 8) scala> scores -= "Alice" //remove res12: scores.type = Map(Bob -> 10, Fred -> 7, Cindy -> 8)
Iterating over Maps:for ((k, v) <- map) process k and v
The magic here is that you can use pattern matching in a Scala for loop. That way, you get the key and value of each pair in the map without any tedious method calls.
scala> scores.keySet res13: scala.collection.Set[String] = Set(Bob, Fred, Cindy) scala> for (v <- scores.values) println(v) 10 7 8
Reverse a map: for ((k, v) <- map) yield (v, k)
Sorted Maps
When working with a map, you need to choose an implementation—a hash table or a balanced tree. By default, Scala gives you a hash table. You might want a tree map if you don’t have a good hash function for the keys, or if you need to visit the keys in sorted order.
scala> val scores = scala.collection.immutable.SortedMap("Alice" -> 10,"Fred" -> 7, "Bob" -> 3, "Cindy" -> 8) scores: scala.collection.immutable.SortedMap[String,Int] = Map(Alice -> 10, Bob -> 3, Cindy -> 8, Fred -> 7)
Tuples
Unlike array or string positions, the component positions of a tuple start with 1 , not 0.
scala> val t = (1, 3.14, "Fred") t: (Int, Double, String) = (1,3.14,Fred) scala> val second = t._2 // Sets second to 3.14 second: Double = 3.14 scala> val (first, second, third) = t // Sets first to 1, second to 3.14, third to "Fred" first: Int = 1 second: Double = 3.14 third: String = Fred
You can use a _ if you don’t need all components:
scala> val (first, second, _) = t first: Int = 1 second: Double = 3.14
Tuples are useful for functions that return more than one value. For example:
scala> "New York".partition(_.isUpper) // Yields the pair ("NY", "ew ork") res15: (String, String) = (NY,ew ork)
Zipping
scala> val symbols = Array("<", "-", ">") symbols: Array[String] = Array(<, -, >) scala> val counts = Array(2, 10, 2) counts: Array[Int] = Array(2, 10, 2) scala> val pairs = symbols.zip(counts)//an array of tuples pairs: Array[(String, Int)] = Array((<,2), (-,10), (>,2)) scala> for ((s, n) <- pairs) Console.print(s * n) <<---------->>
If you have a collection of keys and a parallel collection of values, then zip them up and turn them into a map like this:
keys.zip(values).toMap