Scala 如何更新可变映射的值,该值是主映射键的值?

Scala 如何更新可变映射的值,该值是主映射键的值?,scala,Scala,我在Scala中有一个可变映射,定义如下: scala> var sm = mutable.Map[String, mutable.Map[Int, Int]]() sm: scala.collection.mutable.Map[String,scala.collection.mutable.Map[Int,Int]] = Map() 我有一个地图,它有另一个地图作为它的值&在其中插入值,如下所示 scala> sm += ("abc" -> mutable.Map(1-&

我在Scala中有一个可变映射,定义如下:

scala> var sm = mutable.Map[String, mutable.Map[Int, Int]]()
sm: scala.collection.mutable.Map[String,scala.collection.mutable.Map[Int,Int]] = Map()
我有一个地图,它有另一个地图作为它的值&在其中插入值,如下所示

scala> sm += ("abc" -> mutable.Map(1->0,0->0))
res77: scala.collection.mutable.Map[String,scala.collection.mutable.Map[Int,Int]] = Map(abc -> Map(1 -> 0, 0 -> 0))

scala> sm
res78: scala.collection.mutable.Map[String,scala.collection.mutable.Map[Int,Int]] = Map(abc -> Map(1 -> 0, 0 -> 0))
我的“abc”来自另一个值为0或1的文件,我需要验证并获取0和1的计数,并在映射
sm
中更新它。 在验证之前,我尝试更新scala REPL上的值,如下所示

scala> sm += ("abc" -> (1 -> sm("abc")(1)+1))
<console>:27: error: type mismatch;
 found   : Int(1)
 required: String
       sm += ("abc" -> (1 -> sm("abc")(1)+1))
但是,当我在地图
sm
上替换相同的表达式
sm(“abc”)(1)
,以更新
sm(“abc”)(1)
的值时,我看到错误消息:

scala> sm += ("abc" -> (1 -> sm("abc")(1)+2))
<console>:27: error: type mismatch;
 found   : Int(2)
 required: String
       sm += ("abc" -> (1 -> sm("abc")(1)+2))
scala> var e = sm("abc")(1)+2
e: Int = 2

scala> sm += ("abc" -> (1 -> e ))
<console>:29: error: type mismatch;
 found   : (Int, Int)
 required: scala.collection.mutable.Map[Int,Int]
       sm += ("abc" -> (1 -> e ))
我无法理解此错误消息。有人能告诉我我在这里犯了什么错误,我如何更新地图的->地图的值,并以

Map(abc -> Map(1 -> 2, 0 -> 0))

您的代码存在一些问题:

  • ->
    的优先级高于
    +
    ,因此您的代码基本上是:

    (1 -> sm("abc")(1)) + 2
    
    要使这项工作正常,请在加号周围加上括号:

    1 -> (sm("abc")(1) + 2)
    
    然后它会给您提供关于
    (Int,Int)
    的相同错误

  • 没有从元组(
    ->
    创建元组)到映射的隐式转换,因此需要使用显式构造函数

  • 最终,您的版本的工作代码是:

    sm += ("abc" -> mutable.Map(1 -> (sm("abc")(1) + 2) ) )
    
    然而,这不是一个好的做法。您已经将该值定义为可变映射,因此无需在每次更新该值时构造新映射。另外,您的版本也会丢失该对
    0->0
    。您只需执行以下操作:

    sm("abc")(1) = sm("abc")(1) + 2
    
    sm
    随后将成为
    Map(abc->Map(1->2,0->0))


    另一种解决方法是使用不可变映射。网上有很多关于这个的教程,所以我不在这里重复。

    对包含其他可变对象的可变对象的可变引用。。。听起来你会很头疼。
    sm += ("abc" -> mutable.Map(1 -> (sm("abc")(1) + 2) ) )
    
    sm("abc")(1) = sm("abc")(1) + 2