Сейчас я с удивлением узнаю, что 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
создает view
, _ + 0.1 * rand.nextGaussian
всегда переоценивается всякий раз, когда используется perturbed
.
Теперь я делаю что-то вроде distribution map { case (s, p) => (s, p + 0.1 * rand.nextGaussian) }
, но это немного немного многословно. Поэтому цель этого вопроса:
- Напомните людям, которые не знают об этом факте.
- Посмотрите, почему они делают вывод
mapValues
view
s. - Существует ли альтернативный метод, который создает конкретный
Map
. - Существуют ли какие-либо другие широко используемые методы сбора, которые имеют эту ловушку.
Спасибо.