问题描述
刚才我惊讶地发现 mapValues
生成了一个视图.结果如下例所示:
Just now I am surprised to learn that mapValues
produces a view. The consequence is shown in the following example:
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
产生了一个 view
,_ + 0.1 * rand.nextGaussian
总是重新计算 _ + 0.1 * rand.nextGaussian
使用代码>扰动.
The idea is that I have a distribution, which is perturbed with some randomness then I renormalize it. The code actually fails in its original intention: since mapValues
produces a view
, _ + 0.1 * rand.nextGaussian
is always re-evaluated whenever perturbed
is used.
我现在正在做类似 distribution map { case (s, p) =>(s, p + 0.1 * rand.nextGaussian) }
,但这只是有点冗长.所以这个问题的目的是:
I am now doing something like distribution map { case (s, p) => (s, p + 0.1 * rand.nextGaussian) }
, but that's just a little bit verbose. So the purpose of this question is:
- 提醒不知道这一事实的人.
- 寻找他们使
mapValues
输出view
s 的原因. - 是否有替代方法可以生成具体的
Map
. - 有没有其他常用的收集方法有这个陷阱.
- Remind people who are unaware of this fact.
- Look for reasons why they make
mapValues
outputview
s. - Whether there is an alternative method that produces concrete
Map
. - Are there any other commonly-used collection methods that have this trap.
谢谢.
推荐答案
有一张关于这个的票,SI-4776(由 YT 提供).
There's a ticket about this, SI-4776 (by YT).
介绍它的提交是这样说的:
The commit that introduces it has this to say:
根据 jrudolph 的建议,制作了 filterKeys
和 mapValues
转换抽象映射和不可变的重复功能地图.将 transform
和 filterNot
从不可变映射到通用映射.由 phaler 审核.
我无法找到 jrudolph 的原始建议,但我认为这样做是为了使 mapValues
更有效率.提出这个问题,这可能会让人感到意外,但 mapValues
如果您不太可能对这些值进行多次迭代,则效率会更高.
I have not been able to find the original suggestion by jrudolph, but I assume it was done to make mapValues
more efficient. Give the question, that may come as a surprise, but mapValues
is more efficient if you are not likely to iterate over the values more than once.
作为一种变通方法,可以执行 mapValues(...).view.force
来生成新的 Map
.
As a work-around, one can do mapValues(...).view.force
to produce a new Map
.
这篇关于Scala:为什么 mapValues 会生成一个视图,是否有任何稳定的替代方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!