【问题标题】:What is the proper way to remove elements from a scala mutable map using a predicate使用谓词从 scala 可变映射中删除元素的正确方法是什么
【发布时间】:2011-01-30 19:53:23
【问题描述】:

如何在不创建任何新集合的情况下做到这一点?还有比这更好的吗?

val m = scala.collection.mutable.Map[String, Long]("1" -> 1, "2" -> 2, "3" -> 3, "4" -> 4)
m.foreach(t => if (t._2 % 2 == 0) m.remove(t._1))
println(m)

附:在 Scala 2.8 中

【问题讨论】:

  • 关于收藏的问题应该说明是寻求 2.7 还是 2.8 的答案。
  • 2.8用了好久,2.7都忘了。谢谢,添加了 P.S.
  • 您可以添加一个 Scala-2.8 标签,以表明这是一个 2.8 特定问题。
  • 谢谢,用它替换了“谓词”

标签: scala scala-2.8 mutable scala-collections


【解决方案1】:

retain 做你想做的事。在 2.7 中:

val a = collection.mutable.Map(1->"one",2->"two",3->"three")
a: scala.collection.mutable.Map[Int,java.lang.String] = 
  Map(2 -> two, 1 -> one, 3 -> three)

scala> a.retain((k,v) => v.length < 4)   

scala> a
res0: scala.collection.mutable.Map[Int,java.lang.String] =
  Map(2 -> two, 1 -> one)

它也可以工作,但我认为在 2.8 中仍在不断变化。

【讨论】:

  • 看起来在 2.8 中不推荐使用保留:​​scala-lang.org/archives/downloads/distrib/files/nightly/docs/… 已弃用:由于 Iterable 中的保留,无法推断类型。
  • 确实;他们可能不得不重命名它,或者想出一些其他的解决方法。我不认为它会消失。那有点傻。我将这种弃用解释为“不断变化,可能会改变”。
  • 看起来弃用将被删除。所以答案是正确的。
【解决方案2】:

根据 Scala 可变映射 reference page,您可以使用 -= 或 remove 删除单个元素,如下所示:

val m = scala.collection.mutable.Map[String, Long]("1" -> 1, "2" -> 2, "3" -> 3, "4" -> 4)
m -= "1" // returns m
m.remove("2") // returns Some(2)

不同之处在于 -= 返回原始地图对象,而 remove 返回一个 Option 包含与已删除键对应的值(如果有的话)。

当然,正如其他答案所表明的,如果您想根据条件删除许多元素,您应该考虑保留、过滤等。

【讨论】:

    【解决方案3】:

    如果您使用的是 immutable.Map,在 2.7 中它可能必须是这样的:

    def pred(k: Int, v: String) = k % 2 == 0
    
    m --= (m.filter(pred(_, _)).keys
    

    因为没有可用的retain 方法。显然在这种情况下m 必须声明为var

    【讨论】:

    • 如果您使用的是不可变 Map 并因此必须创建一个新的 Map,那么简单地使用谓词的否定进行过滤非常容易。
    • 确实,这是真的:这取决于你觉得在特定情况下什么更易读
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 2011-08-03
    • 2019-10-09
    • 2011-05-15
    相关资源
    最近更新 更多