2010-03-23 22 views
14

Comment faire cela sans créer de nouvelles collections? Y a-t-il quelque chose de mieux que cela?Quelle est la bonne façon de supprimer des éléments d'une carte scala mutable en utilisant un prédicat

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. dans Scala 2,8

+4

Les questions sur les collections devraient indiquer si une réponse de 2,7 ou 2,8 est recherchée. –

+0

En utilisant 2.8 depuis assez longtemps, déjà oublié 2.7. Merci, a ajouté P.S. –

+2

Il y a un tag Scala-2.8 que vous pourriez ajouter pour indiquer qu'il s'agit d'une question spécifique à 2.8. – ams

Répondre

18

retain fait ce que vous voulez. 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) 

Il fonctionne aussi, mais je pense qu'il est toujours en pleine mutation, à 2,8.

+1

On dirait que retenir est déconseillé dans 2.8: http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/scala/collection/Map .html déprécié: ne peut pas être déduit de type en raison de conserver dans Iterable. –

+0

En effet; ils pourraient avoir à le renommer, ou venir avec une autre solution de contournement. Je ne pense pas que ça va juste disparaître; Ce serait un peu bête. J'interprète cette dépréciation comme «en mouvement, pourrait changer». –

+0

On dirait que la dépréciation va être supprimée. Donc la réponse est correcte. –

0

Si vous utilisez un immutable.Map, dans 2.7 il pourrait être quelque chose comme:

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

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

Comme il n'y a pas de méthode retain disponible. Il est évident que dans ce cas m doit être déclarée comme var

+0

Si vous utilisez une carte immuable et que vous devez en créer une nouvelle, il est assez facile de la filtrer simplement avec la négation du prédicat. –

+0

En effet, cela est vrai: cela dépend de ce que vous ressentez est plus lisible dans une situation donnée –

2

par la Scala carte mutable reference page, vous pouvez supprimer un seul élément avec soit - = ou supprimer, comme ceci:

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 différence est que - = renvoie l'objet carte d'origine, tandis que remove renvoie une option contenant la valeur correspondant à la clé supprimée (s'il y en avait une.)

Bien sûr, comme d'autres réponses l'indiquent, si vous souhaitez supprimer de nombreux éléments en fonction d'une condition , vous devriez regarder dans retenir, filtre, etc