【问题标题】:Scala nested collection assignmentScala 嵌套集合赋值
【发布时间】:2013-01-26 23:46:58
【问题描述】:

我正在尝试在 Scala 中构建一个从整数到一组可变整数的可变映射。

例如,我想要 1 -> (2,3) 形式的映射并能够更新 他们稍后使用键值。我使用的代码如下:

import scala.collection.mutable._

val map = Map[Int, Set[Int]]()
map: scala.collection.mutable.Map[Int,scala.collection.mutable.Set[Int]] = Map()

map += (1 -> Set(2,3))
res15: map.type = Map(1 -> Set(2, 3))

到目前为止还不错,但是当我尝试做类似的事情时

map.get(1) += 4

我得到一个赋值给 val 错误。令我困惑的是 map.get() 应该返回一个 可更新的 scala.collection.mutable.Set 类型集。有人可以请脱一些吗 点亮这里发生了什么?

【问题讨论】:

  • 你应该接受你的问题的一些答案,顺便说一句:)

标签: scala collections


【解决方案1】:

这种情况下的问题是 get() 返回一个选项 (Option[scala.collection.mutable.Set[Int]]),您需要“解包”:

map.get(1).get += 4

Map 的get() 函数返回一个选项的原因是任何给定的键都可能没有值,而且 Scala 不喜欢像其 Java API 对应物那样抛出异常。

您也可以使用apply() 方法,该方法直接返回请求的值并在失败时抛出异常:

map(1) += 4

不过,我还没有完全弄清楚为什么您尝试过的代码会出现“reassignment to val”错误。在我的例子中(Scala 2.10),它说如下:

<console>:12: error: value += is not a member of Option[scala.collection.mutable.Set[Int]]
          map.get(1) += 1

您使用的是哪个版本的 Scala?

【讨论】:

  • 谢谢!很好的答案。我在 2.9.2。现在我也有充分的理由升级了。
  • 另一个与我之前的问题相关的问题:如果我将集合定义为 var map = Map[Int, Set[Int]](),这次使用不可变集合但 var,我再次得到当我尝试类似 map(1) += 4 时,错误重新分配给 val (我仍在使用 scala 2.9.2)。我认为这是因为 Set[Int] 是不可变的。您知道这种情况的任何解决方法吗?
  • Seq 甚至没有 += 方法。在任何情况下,您都无法向不可变的数据结构添加任何内容,如果您能找到一种方法来做到这一点,那将是一个错误,应该尽快修复,因为在许多情况下,当使用不可变数据结构时,您依赖它们是不可变的。
  • 抱歉,我认为我的解释有误导性。更好的问题是如何从现有的 Map[Int, Set[Int]] 创建一个新的 Map[Int, Set[Int]],应用我的更改并将结果放回定义的变量。如果我没有嵌套集合,也没关系,例如:var map = Map((1-&gt;3),(2-&gt;3),(3-&gt;4)) 然后map += (2-&gt;4) 结果将是scala.collection.immutable.Map[Int,Int] = Map(1 -&gt; 3, 2 -&gt; 4, 3 -&gt; 4) 在这里,Scala 为我创建了一个应用了更改的新副本。但是当我在里面有嵌套的 Set 时,它就不起作用了。现在清楚了吗?
  • 如果我正确理解了您的问题,您希望实现我在this answer 中解释的内容。
【解决方案2】:

更优雅的方式是

map.get(1).map(_ += 4).getOrElse{map += 1 -> Seq(4)}

【讨论】:

    猜你喜欢
    • 2012-12-08
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2015-02-05
    相关资源
    最近更新 更多