考虑以下
val myMap: Map[String, List[Int]] = Map("a" -> List(1,2,3),
"b" -> List(4,5,6),
"d" -> List(7))
val possibleKeys: List[String] = List("c","a", "b", "e")
我想遍历可能的键,如果映射包含一个键,遍历映射的值
我想到的选项是:
带过滤器
for {
key <- possibleKeys
if (myMap contains key)
int <- myMap(key)
r <- 0 to int
} yield (r, int)
With getOrElse
for {
key <- possibleKeys
int <- myMap.getOrElse(key, Nil)
r <- 0 to int
} yield (r, int)
(两者返回相同的结果:)
List((0,1), (1,1), (0,2), (1,2), (2,2), (0,3), (1,3), (2,3), (3,3), (0,4), (1,4), (2,4), (3,4), (4,4), (0,5), (1,5), (2,5), (3,5), (4,5), (5,5), (0,6), (1,6), (2,6), (3,6), (4,6), (5,6), (6,6))
因为我知道Scala在推导式中支持选项,所以我有点惊讶这不能工作
for {
key <- possibleKeys
int <- myMap.get(key)
r <- 0 to int //<-- compilation error
} yield (r, int)
它抱怨type mismatch; found : List[Int] required: Int
我模糊地理解为什么,但是有没有一种方法可以在没有if
子句或getOrElse
方法的情况下完成这项工作?(例如,是否有一种方法来获得myMap.get(key)
版本的工作?)
为了便于理解,您正在尝试将不兼容的类型混合在一起。您可以通过示例将该选项转换为Seq来修复它。
for {
key <- possibleKeys
ints <- myMap.get(key).toSeq
int <- ints
r <- 0 to int
} yield (r, int)
在这个非常相似的问题中有一个相当好的解释:Scala For Comprehension上的类型不匹配。
您可以在Map
上使用keySet
和apply
方法
for {
key <- possibleKeys
if myMap.keySet(key)
int <- myMap(key)
r <- 0 to int
} yield (r, int)
res5: List[(Int, Int)] = List((0,1), (1,1), (0,2), (1,2), (2,2), (0,3), (1,3), (2,3), (3,3), (0,4), (1,4), (2,4), (3,4), (4,4), (0,5), (1,5), (2,5), (3,5), (4,5), (5,5), (0,6), (1,6), (2,6), (3,6), (4,6), (5,6), (6,6))