我有以下Array[Int]
:val array = Array(1, 2, 3)
,我在Int和String之间有以下映射关系:
val a1 = array.map{
case 1 => "A"
case 2 => "B"
case 3 => "C"
}
要创建Map
以包含上述映射关系,我知道我可以使用foldLeft
方法:
val a2 = array.foldLeft(Map[String, Int]()) { (m, e) =>
m + (e match {
case 1 => ("A", 1)
case 2 => "B" -> 2
case 3 => "C" -> 3
})
}
输出:
a2:scala.collection.immutable.Map [String,Int] = Map(A - > 1,B - > 2,C - > 3)
这是我想要的结果。 但是我可以通过map
方法获得相同的结果吗?
以下代码不起作用:
val a3 = array.map[(String, Int), Map[String, Int]] {
case 1 => ("A", 1)
case 2 => ("B", 2)
case 3 => ("C", 3)
}
map
的签名是
def map[B, That](f: A => B)
(implicit bf: CanBuildFrom[Repr, B, That]): That
这是CanBuildFrom[Repr, B, That]
是什么?我试着阅读Tribulations of CanBuildFrom,但并不理解。那篇文章提到Scala 2.12+为map
提供了两个实现。但是当我使用Scala 2.12.4时,为什么我找不到它?
我主要使用Scala 2.11.12。
答案 0 :(得分:3)
在表达式的末尾调用val a3 = array.map {
case 1 => ("A", 1)
case 2 => ("B", 2)
case 3 => ("C", 3)
}.toMap
:
query=Color:red,yellow,black AND Size:middle
答案 1 :(得分:2)
基本上toMap
(信用Sergey Lagutin)是正确答案。
您实际上可以使代码更紧凑:
val a1 = array.map { i => ((i + 64).toChar, i) }.toMap
如果您运行此代码:
val array = Array(1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 0)
val a1 = array.map { i => ((i + 64).toChar, i) }.toMap
println(a1)
您将在控制台上看到这一点:
Map(E -> 5, J -> 10, F -> 6, A -> 1, @ -> 0, G -> 7, L -> 12, B -> 2, C -> 3, H -> 8, K -> 11, D -> 4)
答案 2 :(得分:2)
为了简洁起见,我先在这里定义你的功能:
// worth noting that this function is effectively partial
// i.e. will throw a `MatchError` if n is not in (1, 2, 3)
def toPairs(n: Int): (String, Int) =
n match {
case 1 => "a" -> 1
case 2 => "b" -> 2
case 3 => "c" -> 3
}
一种可行的方法(正如另一个答案中已经突出显示的那样)是使用toMap
,它只适用于对的集合:
val ns = Array(1, 2, 3)
ns.toMap // doesn't compile
ns.map(toPairs).toMap // does what you want
值得注意的是,除非您使用惰性表示(如Iterator
或Stream
),否则将导致对集合进行两次传递并创建不必要的中间集合:第一次将toPairs
映射到集合上,然后将整个集合从一组对转变为Map
(toMap
)。
您可以在the implementation of toMap
中清楚地看到它。
正如您在答案中已经链接的阅读中所建议的那样(特别是here)您可以通过两种方式避免这种双重传递:
scala.collection.breakOut
,CanBuildFrom
的实现,您可以map
(以及其他)更改目标集合,前提是您明确为编译器提供类型提示:val resultMap: Map[String, Int] = ns.map(toPairs)(collection.breakOut)
val resultSet: Set[(String, Int)] = ns.map(toPairs)(collection.breakOut)
ns.view.map(toPairs).toMap
您可以在this Q&A中阅读有关隐式构建器提供程序和视图的更多信息。