We continue the journey on Scala on the topic of Maps in this post. For
all the work in this post, we will use Read-Evaluate-Print-Loop
Scala interpreter. Some familiarity
with Java will be of great help in understanding Scala. In this post, we will
look at how Maps are defined along with some features of Maps in Scala.
Map is a collection that has elements in the form of a pair of sub elements: one is a key and the other is a value. Keys have to be unique while values need not.
We can define maps as shown below:
1) An empty map that has a keys of type String and values of type Int:
val Map0: Map[String,Int] = Map()
The results are shown below:
scala> val Map0: Map[String,Int] = Map()
Map0: Map[String,Int] = Map()
2) A Map initialized with key, value pairs:
val Map1: Map[String,Int] = Map("King" -> 24000, "Kochhar" -> 17000, "De Haan" -> 17000)
The results are shown below:
scala> val Map1: Map[String,Int] = Map("King" -> 24000, "Kochhar" -> 17000, "De Haan" -> 17000)
Map1: Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000)
In the above case, to show the association between employee name and the corresponding salary, an arrow symbol, -> is used. Another way to create a Map is shown where name and salary and together in parentheses. We are using an mix of both below:
val Map2: Map[String,Int] = Map(("De Haan" -> 17000),("Hunold", 9000), ("Ernst", 6000), ("Austin", 4800))
The results are shown below:
scala> val Map2: Map[String,Int] = Map(("De Haan" -> 17000),("Hunold", 9000), ("Ernst", 6000), ("Austin", 4800))
Map2: Map[String,Int] = Map(De Haan -> 17000, Hunold -> 9000, Ernst -> 6000, Austin -> 4800)
Thus, we have created two maps. Like Sets, there are the mutable and immutable Maps.
There are many operations that can be performed that are common with Arrays, Vectors and Sets. In this post, we will look at some operations.
1) + : Adds one or more key, value pairs
scala> Map1
res81: Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000)
scala> Map1 + (("AddKey" -> 100))
res82: scala.collection.immutable.Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000, AddKey -> 100)
scala> Map1
res83: Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000)
scala> Map1 + (("AddKey" -> 100),("AddMoreKey",1000))
res84: scala.collection.immutable.Map[String,Int] = Map(King -> 24000, AddMoreKey -> 1000, Kochhar -> 17000, De Haan -> 17000, AddKey -> 100)
scala> Map1
res85: Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000)
2) ++ : Adds two maps
scala> Map1 ++ Map2
res86: scala.collection.immutable.Map[String,Int] = Map(King -> 24000, Ernst -> 6000, Kochhar -> 17000, De Haan -> 17000, Austin -> 4800, Hunold -> 9000)
3) - : Removes a key value when a key is passed
scala> Map1 - ("King")
res91: scala.collection.immutable.Map[String,Int] = Map(Kochhar -> 17000, De Haan -> 17000)
4) apply : Returns value associated with a key
scala> Map1 apply ("King")
res93: Int = 24000
5) filter: filters based on both key and value criteria
scala> Map1.filter((test:(String,Int)) => (test._1).startsWith("De"))
res114: scala.collection.immutable.Map[String,Int] = Map(De Haan -> 17000)
scala> Map1.filter((test:(String,Int)) => test._2 >=19000)
res118: scala.collection.immutable.Map[String,Int] = Map(King -> 24000)
scala> Map1.filter((test:(String,Int)) => (test._1).startsWith("Ki") & test._2 >=19000)
res119: scala.collection.immutable.Map[String,Int] = Map(King -> 24000)
6) filterKeys : filters based on key
scala> Map1.filterKeys(_.startsWith("De"))
res96: scala.collection.immutable.Map[String,Int] = Map(De Haan -> 17000)
7) getOrElse : Based on key, gets a value or sets a default if no corresponding key
scala> Map1.getOrElse("King",100000)
res129: Int = 24000
scala> Map1.getOrElse("Queen",100000)
res130: Int = 100000
8) isDefinedAt : Returns a boolean based on presence of a key
scala> Map1.isDefinedAt("King")
res131: Boolean = true
9) keySet: Returns a Set of all keys
scala> Map1.keySet
res132: scala.collection.immutable.Set[String] = Set(King, Kochhar, De Haan)
10) keys : Returns all keys
scala> Map1.keys
res133: Iterable[String] = Set(King, Kochhar, De Haan)
11) keysIterator : Returns an iterator for keys
scala> val Map1_keysIterator1 = Map1.keysIterator
Map1_keysIterator1: Iterator[String] = non-empty iterator
scala> while (Map1_keysIterator1.hasNext) {
| println(Map1_keysIterator1.next())
| }
King
Kochhar
De Haan
12) mapValues: Applies a function on values. We are halving the value as shown below:
scala> Map1.mapValues(n => n/2)
res21: scala.collection.immutable.Map[String,Int] = Map(King -> 12000, Kochhar -> 8500, De Haan -> 8500)
13) sliding: Returns maps in sequence based on sliding window
scala> val Map1_sliding1 = Map1.sliding(2)
Map1_sliding1: Iterator[scala.collection.immutable.Map[String,Int]] = non-empty iterator
scala> while (Map1_sliding1.hasNext) {
| println(Map1_sliding1.next())
| }
Map(King -> 24000, Kochhar -> 17000)
Map(Kochhar -> 17000, De Haan -> 17000)
14) valuesIterator: Similar to keysIterator but based on values
scala> val Map1_valuesIterator1 = Map1.valuesIterator
Map1_valuesIterator1: Iterator[Int] = non-empty iterator
scala> while (Map1_valuesIterator1.hasNext) {
| println(Map1_valuesIterator1.next())
| }
24000
17000
17000
15) zipAll : Combines two maps with corresponding key, value pairs. If any pairs fall short, then, these are picked up from the next default values
scala> Map1
res13: Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000)
scala> Map2
res14: Map[String,Int] = Map(De Haan -> 17000, Hunold -> 9000, Ernst -> 6000, Austin -> 4800)
scala> Map1.zipAll(Map2,("test1",100),("test2",1000))
res15: scala.collection.immutable.Map[(String, Int),(String, Int)] = Map((King,24000) -> (De Haan,17000), (Kochhar,17000) -> (Hunold,9000), (De Haan,17000) -> (Ernst,6000), (test1,100) -> (Austin,4800))
In the above case, Map1 has fewer key, value pairs than Map2. So, the default value is set in last case
This concludes the discussion of Maps in Scala
Map is a collection that has elements in the form of a pair of sub elements: one is a key and the other is a value. Keys have to be unique while values need not.
We can define maps as shown below:
1) An empty map that has a keys of type String and values of type Int:
val Map0: Map[String,Int] = Map()
The results are shown below:
scala> val Map0: Map[String,Int] = Map()
Map0: Map[String,Int] = Map()
2) A Map initialized with key, value pairs:
val Map1: Map[String,Int] = Map("King" -> 24000, "Kochhar" -> 17000, "De Haan" -> 17000)
The results are shown below:
scala> val Map1: Map[String,Int] = Map("King" -> 24000, "Kochhar" -> 17000, "De Haan" -> 17000)
Map1: Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000)
In the above case, to show the association between employee name and the corresponding salary, an arrow symbol, -> is used. Another way to create a Map is shown where name and salary and together in parentheses. We are using an mix of both below:
val Map2: Map[String,Int] = Map(("De Haan" -> 17000),("Hunold", 9000), ("Ernst", 6000), ("Austin", 4800))
The results are shown below:
scala> val Map2: Map[String,Int] = Map(("De Haan" -> 17000),("Hunold", 9000), ("Ernst", 6000), ("Austin", 4800))
Map2: Map[String,Int] = Map(De Haan -> 17000, Hunold -> 9000, Ernst -> 6000, Austin -> 4800)
Thus, we have created two maps. Like Sets, there are the mutable and immutable Maps.
There are many operations that can be performed that are common with Arrays, Vectors and Sets. In this post, we will look at some operations.
1) + : Adds one or more key, value pairs
scala> Map1
res81: Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000)
scala> Map1 + (("AddKey" -> 100))
res82: scala.collection.immutable.Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000, AddKey -> 100)
scala> Map1
res83: Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000)
scala> Map1 + (("AddKey" -> 100),("AddMoreKey",1000))
res84: scala.collection.immutable.Map[String,Int] = Map(King -> 24000, AddMoreKey -> 1000, Kochhar -> 17000, De Haan -> 17000, AddKey -> 100)
scala> Map1
res85: Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000)
2) ++ : Adds two maps
scala> Map1 ++ Map2
res86: scala.collection.immutable.Map[String,Int] = Map(King -> 24000, Ernst -> 6000, Kochhar -> 17000, De Haan -> 17000, Austin -> 4800, Hunold -> 9000)
3) - : Removes a key value when a key is passed
scala> Map1 - ("King")
res91: scala.collection.immutable.Map[String,Int] = Map(Kochhar -> 17000, De Haan -> 17000)
4) apply : Returns value associated with a key
scala> Map1 apply ("King")
res93: Int = 24000
5) filter: filters based on both key and value criteria
scala> Map1.filter((test:(String,Int)) => (test._1).startsWith("De"))
res114: scala.collection.immutable.Map[String,Int] = Map(De Haan -> 17000)
scala> Map1.filter((test:(String,Int)) => test._2 >=19000)
res118: scala.collection.immutable.Map[String,Int] = Map(King -> 24000)
scala> Map1.filter((test:(String,Int)) => (test._1).startsWith("Ki") & test._2 >=19000)
res119: scala.collection.immutable.Map[String,Int] = Map(King -> 24000)
6) filterKeys : filters based on key
scala> Map1.filterKeys(_.startsWith("De"))
res96: scala.collection.immutable.Map[String,Int] = Map(De Haan -> 17000)
7) getOrElse : Based on key, gets a value or sets a default if no corresponding key
scala> Map1.getOrElse("King",100000)
res129: Int = 24000
scala> Map1.getOrElse("Queen",100000)
res130: Int = 100000
8) isDefinedAt : Returns a boolean based on presence of a key
scala> Map1.isDefinedAt("King")
res131: Boolean = true
9) keySet: Returns a Set of all keys
scala> Map1.keySet
res132: scala.collection.immutable.Set[String] = Set(King, Kochhar, De Haan)
10) keys : Returns all keys
scala> Map1.keys
res133: Iterable[String] = Set(King, Kochhar, De Haan)
11) keysIterator : Returns an iterator for keys
scala> val Map1_keysIterator1 = Map1.keysIterator
Map1_keysIterator1: Iterator[String] = non-empty iterator
scala> while (Map1_keysIterator1.hasNext) {
| println(Map1_keysIterator1.next())
| }
King
Kochhar
De Haan
12) mapValues: Applies a function on values. We are halving the value as shown below:
scala> Map1.mapValues(n => n/2)
res21: scala.collection.immutable.Map[String,Int] = Map(King -> 12000, Kochhar -> 8500, De Haan -> 8500)
13) sliding: Returns maps in sequence based on sliding window
scala> val Map1_sliding1 = Map1.sliding(2)
Map1_sliding1: Iterator[scala.collection.immutable.Map[String,Int]] = non-empty iterator
scala> while (Map1_sliding1.hasNext) {
| println(Map1_sliding1.next())
| }
Map(King -> 24000, Kochhar -> 17000)
Map(Kochhar -> 17000, De Haan -> 17000)
14) valuesIterator: Similar to keysIterator but based on values
scala> val Map1_valuesIterator1 = Map1.valuesIterator
Map1_valuesIterator1: Iterator[Int] = non-empty iterator
scala> while (Map1_valuesIterator1.hasNext) {
| println(Map1_valuesIterator1.next())
| }
24000
17000
17000
15) zipAll : Combines two maps with corresponding key, value pairs. If any pairs fall short, then, these are picked up from the next default values
scala> Map1
res13: Map[String,Int] = Map(King -> 24000, Kochhar -> 17000, De Haan -> 17000)
scala> Map2
res14: Map[String,Int] = Map(De Haan -> 17000, Hunold -> 9000, Ernst -> 6000, Austin -> 4800)
scala> Map1.zipAll(Map2,("test1",100),("test2",1000))
res15: scala.collection.immutable.Map[(String, Int),(String, Int)] = Map((King,24000) -> (De Haan,17000), (Kochhar,17000) -> (Hunold,9000), (De Haan,17000) -> (Ernst,6000), (test1,100) -> (Austin,4800))
In the above case, Map1 has fewer key, value pairs than Map2. So, the default value is set in last case
This concludes the discussion of Maps in Scala