无法更新循环(或映射)中的可变 Scala 集合

Unable to update a mutable Scala collection inside a loop (or map)

提问人:Shashi K 提问时间:11/15/2016 最后编辑:Shashi K 更新时间:11/15/2016 访问量:771

问:

我有一个可变的 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 会返回到原始集。

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

请帮忙!

编辑: 我正在使用 spark-shell REPL.(spark 1.6.1)

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

斯卡拉 循环 Apache 火花 收集 可变

评论

0赞 rethab 11/15/2016
顾名思义,它映射到一个结构上。它不是用来更新事物,而是转换所述结构的元素。你真的尝试过不可变版本吗?我认为这可以通过使用递归更优雅(和功能化)来解决。map
2赞 Suma 11/15/2016
“valueSet 的内容仍然是:Set(0, 1, 2).”。不,它没有。我刚刚在 REPL 中尝试过,以确保。的内容更改为 。也许你在地图上所做的不是,而是?valueSetSet(0, 2)valueSet -= 1valueSet - 1
0赞 Shashi K 11/15/2016
是的,我必须以一种优雅的方式来研究它。我只是想让一些肮脏的东西快速开始工作
0赞 Suma 11/16/2016
如果这是一个 Spark 问题,你也许应该发布一个真正的 Spark 代码,而不是不能代表你正在解决的问题的东西。

答:

1赞 FaigB 11/15/2016 #1

它工作并根据条目的存在删除条目

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

  println(valueSet.size) //size = 0 

评论

0赞 Shashi K 11/15/2016
是的,就在我发布这篇文章之后,我正在尝试一些事情,并发现只有当我们应用地图的对象本质上是分布式的,比如 RDD 时,它才起作用
1赞 jacks 11/15/2016 #2

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

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

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