1. ホーム
  2. scala

[解決済み] MapのmapValuesとtransformの違いについて

2022-03-14 20:09:32

質問

Scalaの場合 Map (参照 API とのセマンティクスとパフォーマンスの違いは何ですか? mapValuestransform ?

任意のマップに対して、例えば

val m = Map( "a" -> 2, "b" -> 3 )

両方

m.mapValues(_ * 5)
m.transform( (k,v) => v * 5 )

は同じ結果をもたらします。

解決方法は?

例えば Map[A,B] . 明確にするために 私は、常に不変の Map .

mapValues は関数を取ります。 B => C ここで C は値の新しい型です。

transform は関数を取ります。 (A, B) => C ここで、この C は、値の型でもある。

そのため、どちらも結果的に Map[A,C] .

しかし transform 関数では、キーの値によって新しい値の結果に影響を与えることができます。

例えば

val m = Map( "a" -> 2, "b" -> 3 )
m.transform((key, value) => key + value) //Map[String, String](a -> a2, b -> b3)

これを mapValues はかなり難しいでしょう。

次に違うのは transform はストリクトであるのに対し mapValues はビューだけを提供し、更新された要素は保存されません。このような感じです。

protected class MappedValues[C](f: B => C) extends AbstractMap[A, C] with DefaultMap[A, C] {
  override def foreach[D](g: ((A, C)) => D): Unit = for ((k, v) <- self) g((k, f(v)))
  def iterator = for ((k, v) <- self.iterator) yield (k, f(v))
  override def size = self.size
  override def contains(key: A) = self.contains(key)
  def get(key: A) = self.get(key).map(f)
}

(から引用 https://github.com/scala/scala/blob/v2.11.2/src/library/scala/collection/MapLike.scala#L244 )

つまり、パフォーマンス的には、何がより効果的であるかということになります。もし f は高価で、結果のマップのいくつかの要素にしかアクセスしません。 mapValues の方がいいかもしれません。 f はオンデマンドで適用されるだけです。そうでなければ、私は map または transform .

transform で表現することもできます。 map . 仮に m: Map[A,B]f: (A,B) => C であれば

m.transform(f) は、次のように等価です。 m.map{case (a, b) => (a, f(a, b))}