2010-03-23 20 views
14

¿Cómo hacerlo sin crear nuevas colecciones? ¿Hay algo mejor que esto?¿Cuál es la forma correcta de eliminar elementos de un mapa modificable scala utilizando un predicado

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. en Scala 2.8

+4

Las preguntas sobre las colecciones deben indicar si se busca una respuesta 2.7 o 2.8. –

+0

Usando 2.8 desde hace mucho tiempo, ya olvidé aproximadamente 2.7. Gracias, agregó P.S. –

+2

Hay una etiqueta Scala-2.8 que puede agregar como una indicación de que esta es una pregunta específica de 2.8. – ams

Respuesta

18

retain hace lo que quiere. En 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) 

También funciona, pero creo que todavía está en flujo, en 2.8.

+1

Parece que retiene está en desuso en 2.8: http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/scala/collection/Map .html obsoleto: no se puede inferir el tipo debido a retener en Iterable. –

+0

De hecho; pueden tener que cambiarle el nombre o encontrar alguna otra solución. No creo que desaparezca; eso sería un poco tonto. Estoy interpretando esa desaprobación como "in flux, might change". –

+0

Parece que se eliminará la obsolescencia. Entonces la respuesta es correcta. –

0

Si está utilizando un immutable.Map, en 2,7 podría tener que ser algo como:

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

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

Como no hay retain método disponible. Obviamente, en este caso m debe declararse como un var

+0

Si está utilizando un mapa inmutable y, por lo tanto, debe crear uno nuevo, es bastante fácil simplemente filtrar con la negación del predicado. –

+0

De hecho, esto es cierto: depende de lo que sientas que sea más legible en una situación dada –

2

por el mapa mutable Scala reference page, puede eliminar un solo elemento, ya sea con - = o eliminar, de esta manera:

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) 

La diferencia es que - = devuelve el objeto de mapa original, mientras que remove devuelve una Opción que contiene el valor correspondiente a la clave eliminada (si hubo una).

Por supuesto, como indican otras respuestas, si desea eliminar muchos elementos en función de una condición , deberías mirar retener, filtrar, etc.

Cuestiones relacionadas