为了理解Map查找 - 有更好的方法吗?

时间:2013-04-30 03:10:13

标签: scala map for-comprehension

考虑以下

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)    

使用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)版本起作用?)

2 个答案:

答案 0 :(得分:4)

您正在尝试将不兼容的类型混合到您的理解中。您可以通过示例将选项转换为Seq来修复它。

for {
  key <- possibleKeys
  ints <- myMap.get(key).toSeq
  int <- ints
  r <- 0 to int
} yield (r, int)

这个非常相似的问题对这个问题有一个很好的解释:Type Mismatch on Scala For Comprehension

答案 1 :(得分:0)

您可以在Map

上使用keySetapply方法
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))