0

次のことを考慮してください

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)バージョンを動作させる方法はありますか?)

4

2 に答える 2

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

于 2013-04-30T03:51:17.547 に答える
0

keySetメソッドなどapplyを利用できますMap

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))
于 2013-04-30T08:17:11.400 に答える