Create a map from a collection using the function
I want to create a map from a collection by giving it a mapping function. This is basically equivalent to what a normal method does map
, only I want it to return map
, not a flat collection.
I expect it to have a signature like
def toMap[T, S](T => S): Map[T, S]
when called like this
val collection = List(1, 2, 3)
val map: Map[Int, String] = collection.toMap(_.toString + " seconds")
the expected value map
would be
Map(1 -> "1 seconds", 2 -> "2 seconds", 3 -> "3 seconds")
The method will be equivalent to
val collection = List(1, 2, 3)
val map: Map[Int, String] = collection.map(x => (x, x.toString + " seconds")).toMap
is there such a method in Scala?
source to share
There is no such single method. As you say, you can use map
and then toMap
. If you are worried about the broker list you create, you can use breakOut
as an implicit second argument for map
:
import scala.collection.breakOut
val map: Map[Int, String] = collection.map(x => (x._1, x._2.toString + " seconds"))(breakOut)
You can read more about breakOut
and implicit argument map
here .
This method allows you to create other types, which also have a suitable implementation CanBuildFrom
, without an intermediate step:
val arr: Array[(Int, String)] = collection.map(x => (x._1, x._2.toString + " seconds"))(breakOut)
You might also consider using views, which prevent intermediate collections from being created:
val m = (List("A", "B", "C").view map (x => x -> x)).toMap
The differences between these approaches are described here .
Finally, there is a method mapValues
that might be suitable for your purposes if you are only matching the values of each key and value pair. Be careful, however, as this method actually returns a view and can lead to unexpected performance results.
source to share
scalaz has a method fproduct
for Functors
that returns things in the correct form to call .toMap on the result:
scala> import scalaz._,Scalaz._
import scalaz._
import Scalaz._
scala> val collection = List(1, 2, 3)
collection: List[Int] = List(1, 2, 3)
scala> collection.fproduct(_.toString + " seconds").toMap
res0: scala.collection.immutable.Map[Int,String] = Map(1 -> 1 seconds, 2 -> 2 seconds, 3 -> 3 seconds)
source to share