I tried to use Map.map to convert a map into a List of Tuples. However this fails. I did the following experiments:
val m = Map(("a" -> 1), ("b" -> 2))
//> m : scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2)
val r1 = m.map{ case (k,v) => v} //> r1 : scala.collection.immutable.Iterable[Int] = List(1, 2)
def toTuple[A,B](a:A,b:B) = (a,b) //> toTuple: [A, B](a: A, b: B)(A, B)
//val r2: List[Tuple2[_,_]] = m.map(e => (e._1,e._2))
val r3 = m.map(e => toTuple(e._1,e._2)) //> r3 : scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2)
val r4 = m.toSeq //> r4 : Seq[(String, Int)] = ArrayBuffer((a,1), (b,2))
Notice how a List is generated for single elements (r1) but a Map is produced for tuples (r3). Not even forcing the type worked (r2). Only an explicit call to Seq did it (r4) So my question is, why/how does Map.map "automagically" create a new Map and not a list for example? In fact how is the return type determined (Seq, List, etc.)
map() method is a member of TraversableLike trait, it is used to run a predicate method on each elements of a collection. It returns a new collection.
Scala map is a collection of key/value pairs. Any value can be retrieved based on its key. Keys are unique in the Map, but values need not be unique. ListMap implements immutable map and uses list to implement the same. It is used with small number of elements.
a pair is a tuple that only holds two values. a map is a structure that (conceptually) holds multiple pairs and allows efficient lookups by the first element in the pair (the key). They also do not allow the first elements of any pairs to be the same.
Scala Map get() method with exampleThe get() method is utilized to give the value associated with the keys of the map. The values are returned here as an Option i.e, either in form of Some or None. Return Type: It returns the keys corresponding to the values given in the method as argument.
A Map
is a collection of tuples already.
scala> "b" -> 2
res0: (String, Int) = (b,2) // Implicitly converted to a Tuple
When you're mapping a Map
, you're mapping the (key, value) pairs that it contains. This can't work, because you're stripping away the keys, and retaining only the values. So what you have is no longer a Map
, but a step or two up the collection hierarchy, an Iterable
:
val r1 = m.map{ case (k,v) => v}
Forcing the type cannot work, because a Map[A, B]
is not a List[(A, B)]
. This is the equivalent of m.map(identity)
. Notice how you're even accessing e
with tuple accessors:
val r2: List[Tuple2[_,_]] = m.map(e => (e._1,e._2))
val r3 = m.map(e => toTuple(e._1,e._2))
Here, Seq
is more generalized than List
:
val r4 = m.toSeq
The simple solution as stated by @EndeNeu is to just use toList
. When you map
a collection, it should return the original collection type if it can. So mapping a Map
should return another Map
, unless the underlying structure has made it no longer a Map
(like removing keys entirely) in r1
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With