web-dev-qa-db-fra.com

Scala: Utilisation de HashMap avec une valeur par défaut

J'ai un HashMap mutable et je voudrais l'utiliser comme un dictionnaire par défaut. La méthode évidente semble être d'utiliser getOrElse et de fournir la valeur par défaut à chaque fois comme deuxième valeur. Cependant, cela semble un peu inélégant dans mon cas d'utilisation car la valeur par défaut ne change pas.

var x = HashMap(1 -> "b", 2 -> "a", 3 -> "c")

println(x.getOrElse(4, "_")
println(x.getOrElse(5, "_"))
// And so on...
println(x.getOrElse(10, "_"))

Existe-t-il un moyen de créer un HashMap (ou une classe similaire) de telle sorte que la tentative d'accès à des clés non définies renvoie une valeur par défaut définie lors de la création du HashMap? Je remarque que HashMap.default est juste réglé pour lever une exception mais je me demande si cela peut être changé ...

31
PythonPower

Essaye ça:

import collection.mutable.HashMap
val x = new HashMap[Int,String]()  { override def default(key:Int) = "-" }
x += (1 -> "b", 2 -> "a", 3 -> "c")

Alors:

scala> x(1)
res7: String = b

scala> x(2)
res8: String = a

scala> x(3)
res9: String = c

scala> x(4)
res10: String = -
35
huynhjl

Wow, il m'est arrivé de visiter ce fil exactement un an après avoir publié ma dernière réponse ici. :-)

Scala 2.9.1. mutable.Map est fourni avec une méthode withDefaultValue. REPL session:

scala> import collection.mutable
import collection.mutable

scala> mutable.Map[Int, String]().withDefaultValue("")
res18: scala.collection.mutable.Map[Int,String] = Map()

scala> res18(3)
res19: String = ""
70
missingfaktor
scala> val x = HashMap(1 -> "b", 2 -> "a", 3 -> "c").withDefaultValue("-")
x: scala.collection.immutable.Map[Int,Java.lang.String] = Map((1,b), (2,a), (3,c))

scala> x(3)
res0: Java.lang.String = c

scala> x(5)
res1: Java.lang.String = -

MODIFIER:

Pour mutable.HashMap, vous pouvez effectuer les opérations suivantes:

scala> import collection.mutable
import collection.mutable

scala> val x = new mutable.HashMap[Int, String] {
     |   override def apply(key: Int) = super.get(key) getOrElse "-"
     | }
x: scala.collection.mutable.HashMap[Int,String] = Map()

scala> x += (1 -> "a", 2 -> "b", 3 -> "c")
res9: x.type = Map((2,b), (1,a), (3,c))

scala> x(2)
res10: String = b

scala> x(4)
res11: String = -

Il pourrait y avoir une meilleure façon de procéder. Attendez que les autres répondent.

1
missingfaktor

Je suis plus un Java ... mais si getOrElse n'est pas définitif, pourquoi ne pas simplement étendre HasMap et fournir quelque chose comme ceci:

override def getOrElse(k: Int, default: String) = {
  return super.getOrElse(k,"_")
}

Remarque: la syntaxe est probablement foirée mais j'espère que vous obtiendrez le point

0
Pablo Fernandez