はじめに
Scala においてループ処理は多用されますが、 Map
の key と value をループさせるには少し工夫が必要なのでまとめておきます。
また、 Scala の Map
は Seq[Tuple2]
のように扱えるので、 Seq[TupleN]
にも同様の方法が使えます。
やりたいこと
val source = Map("a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4)
このような Map
に "a" * 1
... を行っていき、以下のような List
を得ます。
List("a", "bb", "ccc", "dddd")
(もう少し実用的な例があればよかったのですが、思いつかなかったので許して )
case
でパターンマッチ
source.map({case (key, value) => key * value})
よく見る気がします。
for
でパターンマッチ
for ((key, value) <- source) yield key * value
形が違うだけで case
とほぼ同じですね。
Fuction.Tupled
source.map(Function.tupled((key, value) => key * value))
あまり見ないのですが、個人的には一番好きです。
Function.Tupled
は FunctionN[引数1, 引数2, ... 戻り値]
を Function1[TupleN[引数1, 引数2, ... ], 戻り値]
に変換する関数です。(わかりづらい…)
source.map(Function.tupled(_ * _))
アンダースコア記法も使えるのが便利です。
普通に map
する
source.map(tuple => tuple._1 * tuple._2)
一番素直?な方法です。
tuple
という引数を定義しないといけないのが微妙です。
おわりに
いかがでしょうか?
4種挙げてみたものの、どれを使うかは好みだと思います。
おまけ
Seq[TupleN]
のループなんて使うの?という意見もありそうなので、自分がよく使うイディオムを貼っておきます。
長さが同じ Seq
をまとめてループさせたい場合です。
インデックスを使ってループさせるよりもきれいに書けます。
val valuesA = Seq(1, 2, 3, 4)
val valuesB = Seq(5, 6, 7, 8)
for ((a, b) <- valuesA zip valuesB) someFunction(a, b)