我遇到了一个问题: 我想改变一个元素,但代码正在改变所有元素。 我一定做错了什么。 这就是我所拥有的:
var critics: Map[String, List[(String, Double)]] = Map(
"First" -> List(("a", 1.0), ("b", 2.0)),
"Second" -> List(("c", 3.0), ("d", 4.0))
)
def setNewRating(keyMap: String, param1: String, newRating: Double) = {
val newList = critics(keyMap).map{case (param1, _) => (param1, newRating); case x => x}
critics = critics + (keyMap -> newList)
}
println(critics)
setNewRating("First", "b", 5.0)
println(critics)
所以,我正在寻找关键字“First”并获取List我希望将“b”从2.0更改为5.0但是我得到的结果是:
critics: Map[String,List[(String, Double)]] = Map(First -> List((a,1.0), (b,2.0)), Second -> List((c,3.0), (d,4.0)))
setNewRating: (keyMap: String, param1: String, newRating: Double)Unit
Map(First -> List((a,1.0), (b,2.0)), Second -> List((c,3.0), (d,4.0)))
Map(First -> List((a,5.0), (b,5.0)), Second -> List((c,3.0), (d,4.0)))
代码更改了所有值!
提前感谢,
答案 0 :(得分:1)
这应该有效。您在case子句param1
中使用的.map{case (param1, _)
与参数中定义的变量param1不同。它是一个新变量param1
,它被赋予隐藏方法参数的Tuple2
的第一个元素的值。
def setNewRating(keyMap: String, param1: String, newRating: Double) = {
val newList = critics(keyMap) map {
case (x, _) if x == param1 => (param1, newRating)
case x => x
}
critics = critics + (keyMap -> newList)
}
答案 1 :(得分:1)
您需要将param1
放入反引号中:
def setNewRating(keyMap: String, param1: String, newRating: Double) = {
val newList = critics(keyMap)
.map {
case (`param1`, _) => param1 -> newRating
case x => x
}
critics = critics + (keyMap -> newList)
}
问题是case (param1, _)
表示“匹配任何内容,并将值存储到新的本地变量param1
”。那不是你想要的。
case (`param1`, _) =>
另一方面,表示“匹配与外部变量param1
相同的值”。
或者,如果您将param1
重命名为Param1
,它也会起作用(显然,scala匹配假定以大写字母开头的所有内容都是常量)。我并不是建议你这样做,只是提到完整性。只需使用反引号。
(另外,使用这样的var
让我感到畏缩,你真的应该找到一种方法来避免它,但这不是你的问题......)
答案 2 :(得分:0)
如果您愿意从List
更改为Set
,则可能只是缺少MultiMap
特质。
可变映射的特征,其中多个值分配给键。
此类通常用作mixin。它将地图A到Set [B]对象的地图转换为将A映射到B对象的多重映射。
您可以找到参考here