追加 - scala mutable map




Scala:なぜmapValuesがビューを生成し、安定した選択肢がありますか? (2)

ちょうど今私はmapValuesがビューを生成することを知ってmapValuesています。 その結果を次の例に示します。

case class thing(id: Int)
val rand = new java.util.Random
val distribution = Map(thing(0) -> 0.5, thing(1) -> 0.5)
val perturbed = distribution mapValues { _ + 0.1 * rand.nextGaussian }
val sumProbs = perturbed.map{_._2}.sum
val newDistribution = perturbed mapValues { _ / sumProbs }

アイデアは、私はいくつかのランダム性を摂動させた後、私はそれを再標準化する分布を持っているということです。 コードは実際には元の意図で失敗します。 mapValues_ + 0.1 * rand.nextGaussianperturbedが使用されるたびに_ + 0.1 * rand.nextGaussian view生成されるためです。

私は現在、 distribution map { case (s, p) => (s, p + 0.1 * rand.nextGaussian) }ようなことをやっていますが、それはちょっと冗長です。 だからこの質問の目的は:

  1. この事実を知らない人々を思い出させる。
  2. mapValues view出力する理由をmapValuesます。
  3. 具体的なMapを生成する代替メソッドがあるかどうか。
  4. このトラップを持つその他の一般的に使用されるコレクションメソッドはありますか?

ありがとう。


scala docは言う:

このマップのすべてのkeyf(this(key))マップするマップビュー。 結果のマップは、要素をコピーせずに元のマップをラップします。

だから、これは期待されるはずですが、これは私に多くの恐怖を、私は明日コードの束を検討する必要があります。 私はそのような行動を期待していなかった:-(

もう一つの回避策:

toSeqを呼び出してコピーを取得し、 toMapにマップする必要がある場合は、この不要なオブジェクトを作成し、 mapを使用することよりもパフォーマンス上の影響がありmap

1つは比較的簡単に書くことができます。これは、ビューを作成しないmapValuesです。私は明日にそれを行い、誰も私の前でコードを投稿しません;)

編集:

mapValuesの後に '.map(identity)'を使用すると、特定の関数を実装する必要はありません。

scala> val xs = Map("a" -> 1, "b" -> 2)
xs: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 1, b -> 2)

scala> val ys = xs.mapValues(_ + Random.nextInt).map(identity)
ys: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 1315230132, b -> 1614948101)

scala> ys
res7: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 1315230132, b -> 1614948101)

返される型は実際にはビューではありません! 他の人は '力'と呼ぶことができたでしょう...


これについてのチケット、 SI-4776 (YTによる)があります。

それを紹介するコミットはこれを言う:

jrudolphの提案に続いて、 filterKeysmapValuesは抽象マップを変換し、不変マップは複写された機能を作りfilterKeystransformfilterNotを不変から一般のマップに移動しました。 phallerによるレビュー。

私はjrudolphによるオリジナルの提案を見つけることができませんでしたが、 mapValuesより効率的にするために行われたと仮定します。 驚くかもしれませんが、 mapValues 、値を複数回反復する可能性が高い場合は、より効率的です。

回避策として、 mapValues(...).view.forceを実行して新しいMapを生成することができます。







map