简体   繁体   English

Scala:更改地图内列表中的值

[英]Scala: change value in list inside a map

I'm facing a problem: I want to change one element inside but the code is changing all elements. 我面临一个问题:我想在其中更改一个元素,但是代码正在更改所有元素。 I must be doing something wrong. 我一定做错了什么。 Here's what I have: 这是我所拥有的:

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)

so, I'm looking for the key "First" and getting the List I want to change the "b" from 2.0 to 5.0 but the result I'm getting is: 因此,我正在寻找键“ First”并获取列表,我想将“ 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)))

The code changed all the values! 代码更改了所有值!

thanks in advance, 提前致谢,

This should work. 这应该工作。 the param1 you use in the case clause .map{case (param1, _) is not the same variable param1 defined in the argument. param1你的情况下子句中使用.map{case (param1, _)不在参数所定义的相同变量参数1。 It is a new variable param1 which is assigned the value of the first element of the Tuple2 that shadows the method argument. 它是一个新变量param1 ,该变量被分配给Tuple2的第一个元素的值,该元素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)
}

You need to put param1 in backticks: 您需要将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)
  }

The problem is that case (param1, _) means "match anything, and store the value into new local variable param1 ". 问题是这种case (param1, _)表示“匹配任何内容,并将值存储到新的局部变量param1 ”。 That's not what you want. 那不是你想要的。

 case (`param1`, _) => 

On the other hand, means "match the value that is the same as the outer variable param1 ". 另一方面,意味着“匹配与外部变量param1相同的值”。

Alternatively, if you renamed param1 to Param1 , it would work too (apparently, scala matching assumes that everything starting with a capital letter is constant). 另外,如果将param1重命名为Param1 ,它也可以工作(显然,scala匹配假定以大写字母开头的所有内容都是常数)。 I am not suggesting you do that, only mentioning it for completeness. 我不建议您这样做,只是为了完整起见。 Just use backticks. 只需使用反引号即可。

(Also, using var like this makes me cringe, you really should find a way to avoid it, but that wasn't your question ...) (此外,像这样使用var使我感到畏缩,您确实应该找到避免这种情况的方法,但这不是您的问题...)

If you are willing to change from List to Set , you might just be missing MultiMap trait. 如果您愿意从List更改为Set ,则可能只是缺少MultiMap特征。

A trait for mutable maps with multiple values assigned to a key. 具有分配给键的多个值的可变映射的特征。

This class is typically used as a mixin. 此类通常用作mixin。 It turns maps which map A to Set[B] objects into multimaps that map A to B objects. 它将将A映射到Set [B]对象的映射转换为将A映射到B对象的多重映射。

You can find the reference here 您可以在这里找到参考

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM