我想通过为集合提供映射功能来创建集合。它基本上等同于普通map
方法所做的,只是我希望它返回Map
,而不是平面集合。
我希望它有像
这样的签名def toMap[T, S](T => S): Map[T, S]
像这样调用
val collection = List(1, 2, 3)
val map: Map[Int, String] = collection.toMap(_.toString + " seconds")
map
的预期值为
Map(1 -> "1 seconds", 2 -> "2 seconds", 3 -> "3 seconds")
该方法等同于
val collection = List(1, 2, 3)
val map: Map[Int, String] = collection.map(x => (x, x.toString + " seconds")).toMap
Scala中有这样的方法吗?
答案 0 :(得分:3)
没有这样的单一方法。如您所说,您可以使用map
后跟toMap
。如果您担心要创建的中间列表,可以考虑使用breakOut
作为map
的隐式第二个参数:
import scala.collection.breakOut
val map: Map[Int, String] = collection.map(x => (x._1, x._2.toString + " seconds"))(breakOut)
您可以详细了解breakOut
以及map
here的隐含参数。
此方法允许您构建具有合适CanBuildFrom
实现的其他类型,而无需中间步骤:
val arr: Array[(Int, String)] = collection.map(x => (x._1, x._2.toString + " seconds"))(breakOut)
您可能还想考虑使用禁止创建中间集合的视图:
val m = (List("A", "B", "C").view map (x => x -> x)).toMap
描述了这些方法之间的差异here。
最后,如果您只映射每个键值对的值,则可以使用mapValues
方法,它可能适合您的用途。但要小心,因为此方法实际上会返回一个视图,并可能导致意外的性能命中。
答案 1 :(得分:3)
scalaz对fproduct
有一个Functors
方法,它返回正确形状的东西,用于在结果上调用.toMap:
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)