ScalaのMapLike
特性にはメソッドがあります
mapValues [C] (f: (B) ⇒ C): Map[A, C]
しかし、私は時々別のタイプが欲しい:
mapKeysAndValues [C] (f: (A, B) ⇒ C): Map[A, C]
これを行う簡単な方法はありますか?もちろん、これは折り目で行うことができます。
ScalaのMapLike
特性にはメソッドがあります
mapValues [C] (f: (B) ⇒ C): Map[A, C]
しかし、私は時々別のタイプが欲しい:
mapKeysAndValues [C] (f: (A, B) ⇒ C): Map[A, C]
これを行う簡単な方法はありますか?もちろん、これは折り目で行うことができます。
回答:
map
メソッドはすべての(key, value)
ペアを反復します。次のように使用できます。
val m = Map("a" -> 1, "b" -> 2)
val incM = m map {case (key, value) => (key, value + 1)}
case
はここで何を達成しますか?
{case (key, value) => ...}
この場合、@ Omnipresent は単なるパターンマッチングです。に関数を提供する代わりにmap
、部分的な関数を与えます。
case
パターンに型を入れることができますが、これはランタイムエラーを発生させる可能性があるため、安全ではありません(これは単なるパターンマッチであるため)。一方、map
関数の下のコレクションの構造を変更して、オブジェクトとして解釈するオブジェクトが少なすぎたり多すぎたりすると(key, value)
、もう一度、実行時エラーが発生するはずです。:(
このコードはどうですか:
val m = Map(1 -> "one", 2 -> "two")
def f(k: Int, v: String) = k + "-" + v
m map {case (k, v) => (k, f(k, v))}
生成されるもの:
Map(1 -> 1-one, 2 -> 2-two)
これはユーティリティメソッドにパッケージ化できます。
def mapKeysAndValues[A,B,C](input: Map[A,B], fun: (A, B) => C) =
input map {case(k,v) => (k, fun(k, v))}
使用法:
mapKeysAndValues(
Map(1 -> "one", 2 -> "two"),
(k: Int, v: String) => k + "-" + v
)
MapLike#transform
ですか?
m map (t => (t._1, t._2 + 1))
m map (t => t._1 -> t._2 + 1)
ユーティリティクラスを作成できます。
class MyMapLike[K,V](m:MapLike[K,V,_]){
def mapKeysAndValues[R](f: (K, V) => R)={
m.map{case (k,v)=> f(k,v)}
}
}
object MyMapLike{
implicit def maplike2mymaplike[K,V](ml:MapLike[K,V,_]):MyMapLike[K,V]=new MyMapLike(m)
}
import MyMapLike._
Map(1 -> "one", 2 -> "two").mapKeysAndValues(k,v=>v*k)
テストされていないコードですが、そのように動作するはずです。
f : (A,B) => (A,C)
簡単にできますm.map(f.tupled)
。で動作しますval f = (x: String, y: Int) => (x, y+1)
が、奇妙なことに、f
と同等に定義すると、replは不平を言いますdef
。