web-dev-qa-db-ja.com

Scala foreachマップ

与えられた:

val m = Map[String, Int]("a" -> 1, "b" -> 2, "c" -> 3)
m.foreach((key: String, value: Int) => println(">>> key=" + key + ", value=" + value))

コンパイラが文句を言うのはなぜですか

error: type mismatch
found   : (String, Int) => Unit
required: (String, Int) => ?
48
Dzhu

おっと、docoを間違って読んで、map.foreachはTuple引数を持つ関数リテラルを期待しています!

そう

m.foreach((e: (String, Int)) => println(e._1 + "=" + e._2))

働く

29
Dzhu

エラーについてはわかりませんが、次のようにして目的を達成できます。

m.foreach(p => println(">>> key=" + p._1 + ", value=" + p._2))

つまり、foreachは2つの引数をとる関数ではなく、ペアをとってUnitを返す関数を受け取ります。ここでは、p(String, Int)

別の書き方は次のとおりです。

m.foreach { case (key, value) => println(">>> key=" + key + ", value=" + value) }

この場合、{ case ... }ブロックは部分的な機能です。

75
Philippe

サブパートkeyvalueに変数を割り当てるには、Tuple2引数をパターン一致させる必要があります。ほんの少しの変更でできます:

m.foreach{ case (key: String, value: Int) => println(">>> key=" + key + ", value=" + value)} 
15
huitseeker

紛らわしいエラーメッセージはコンパイラのバグであり、 2.9.2で修正済み である必要があります。

14
Paul Butcher

素晴らしい質問です! foreachメソッドを明示的に入力した場合でも、非常に不明瞭なコンパイルエラーが発生します。それを回避する方法はありますが、なぜこの例が機能しないのか理解できません。

scala> m.foreach[Unit] {(key: String, value: Int) => println(">>> key=" + key + ", value=" + value)}
<console>:16: error: type mismatch;
 found   : (String, Int) => Unit
 required: (String, Int) => Unit
              m.foreach[Unit] {(key: String, value: Int) => println(">>> key=" + key + ", value=" + value)}
                                                         ^
5
Eishay Smith

文書によると、引数はTuple-> unitなので、これを簡単に行うことができます

Map(1 -> 1, 2 -> 2).foreach(Tuple => println(Tuple._1 +" " + Tuple._2)))
1
vikashait

さらに別の方法:

Map(1 -> 1, 2 -> 2).foreach(((x: Int, y: Int) => ???).tupled)

ただし、明示的な型注釈が必要なため、部分的な機能が優先されます。

0
Yaroslav