views:

177

answers:

2

How to do that without creating any new collections? Is there something better than this?

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)

P.S. in Scala 2.8

+4  A: 

retain does what you want. In 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)

It also works, but I think is still in flux, in 2.8.

Rex Kerr
Looks like retain is deprecated in 2.8:http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/scala/collection/Map.htmldeprecated: cannot be type inferred because of retain in Iterable.
Oleg Galako
Indeed; they might have to rename it, or come up with some other workaround. I don't think it will just vanish; that would be kind of silly. I'm interpreting that deprecation as "in flux, might change".
Rex Kerr
Looks like deprecation is going to be removed. So the answer is correct.
Oleg Galako
A: 

If you are using an immutable.Map, in 2.7 it might have to be something like:

def pred(k: Int, v: String) = k % 2 == 0

m --= (m.filter(pred(_, _)).keys

As there is no retain method available. Obviously in this case m must be declared as a var

oxbow_lakes
If you're using an immutable Map and hence must create a new one, it's pretty easy to simply filter with the negation of the predicate.
Randall Schulz
Indeed, this is true: it depends what you feel is more readable in a given situation
oxbow_lakes