【问题标题】:Unable to update a mutable Scala collection inside a loop (or map)无法更新循环(或映射)内的可变 Scala 集合
【发布时间】:2017-03-29 00:39:50
【问题描述】:

我有一个可变的 scala 集:

val valueSet = scala.collection.mutable.Set[Int](0, 1, 2)

当我表演时

valueSet -= 1 

结果是 Set(0,2)

但是当我在循环或地图中执行相同的操作时:

Range(0, 10).map(entry => valueSet -= 1)
valueSet
res130: scala.collection.mutable.Set[Int] = Set(0, 1, 2)

valueSet 的内容仍然是:Set(0, 1, 2)。

我需要运行一个循环并根据某些条件从 Set 中删除元素,直到循环结束或 Set 变为空。我尝试在循环内打印 valueSet 并且它工作正常但是当循环结束时 valueSet 又回到原来的集合。

使用不可变版本会严重影响代码的性能,这就是我使用可变版本的原因。

请帮忙!

编辑: 我正在使用火花壳 REPL。 (火花 1.6.1)

我又尝试了几件事,发现如果我在 RDD 上执行循环或映射,则它不起作用。但是对于非分布式的集合,它可以工作。我猜这与它是 RDD 上的转换函数并且不执行任何操作有关。但这只是我的猜测。

【问题讨论】:

  • 正如名称map 所暗示的那样,它映射到一个结构上。它不是用来更新事物,而是转换所述结构的元素。你真的尝试过不可变版本吗?我认为这可以通过使用递归更优雅(和功能性)来解决。
  • "valueSet 的内容保持不变:Set(0, 1, 2).".不,不是的。我刚刚在 REPL 中尝试过。 valueSet的内容改为Set(0, 2)。也许你在地图上做的不是valueSet -= 1,而是valueSet - 1
  • 是的,我必须有一种优雅的方式来研究它。我只是想让一些肮脏的东西快速开始工作
  • 如果这是 Spark 问题,您或许应该发布真正的 Spark 代码,而不是不能代表您正在解决的问题的代码。

标签: scala loops apache-spark collections mutable


【解决方案1】:

它可以根据条目的存在来工作和删除条目

val valueSet = scala.collection.mutable.Set[Int](0, 1, 2)
  Range(0, 10).foreach(entry => valueSet -= entry)

  println(valueSet.size) //size = 0 

【讨论】:

  • 是的,就在我发布这个之后,我尝试了一些事情并发现只有当我们应用地图的对象是分布式的对象时它才起作用,比如 RDD
【解决方案2】:

也许是 for 理解 - 因为我猜你的实际谓词比仅仅从集合中删除值 1 更多。它将返回 1 个新的可变集,但您不会为范围内的每个值生成中间集。

scala> for {
     |   x <- valueSet
     |   if(x != 1)     // or whatever
     | } yield x

res1: scala.collection.mutable.Set[Int] = Set(0, 2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-10
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多