class DefaultListMap[A, B <: List[B]] extends HashMap[A, B] {
override def default(key: A) = List[B]()
}
Je ne veux pas créer de carte A -> List[B]
. Dans mon cas, c'est Long -> List[String]
mais lorsque j'obtiens une clé de la carte qui n'a pas de valeur, je voudrais créer List
vide au lieu de Exception
être jeté. J'ai essayé différentes combinaisons mais je ne sais pas comment faire passer le code ci-dessus au compilateur.
Merci d'avance.
Pourquoi ne pas utiliser withDefaultValue (valeur)?
scala> val m = Map[Int, List[String]]().withDefaultValue(List())
m: scala.collection.immutable.Map[Int,List[String]] = Map()
scala> m(123)
res1: List[String] = List()
Plutôt que d'utiliser apply
pour accéder à la carte, vous pouvez toujours utiliser get
, qui renvoie Option[V]
puis getOrElse
:
map.get(k) getOrElse Nil
Une grande fonctionnalité de la bibliothèque de programmation fonctionnelle scalaz est l'opérateur unaire ~
, ce qui signifie "ou zéro", tant que le type de valeur a un "zéro" défini (ce que List
fait, le zéro étant Nil
bien sûr). Le code devient alors:
~map.get(k)
Ceci est doublement utile car la même syntaxe fonctionne là où (par exemple) vos valeurs sont Int
, Double
etc (tout ce qui contient une classe de caractères Zero
).
Il y a eu beaucoup de débats sur la liste de diffusion scala sur l'utilisation de Map.withDefault
en raison de la façon dont cela se comporte alors en ce qui concerne la méthode isDefinedAt
, entre autres. J'ai tendance à m'en éloigner pour cette raison.
Il existe une méthode withDefaultValue
sur Map
:
scala> val myMap = Map(1 -> List(10), 2 -> List(20, 200)).withDefaultValue(Nil)
myMap: scala.collection.immutable.Map[Int,List[Int]] = Map((1,List(10)), (2,List(20, 200)))
scala> myMap(2)
res0: List[Int] = List(20, 200)
scala> myMap(3)
res1: List[Int] = List()
Pourquoi voulez-vous manipuler une carte alors qu'elle a déjà une méthode pour cela?
val m = Map(1L->List("a","b"), 3L->List("x","y","z"))
println(m.getOrElse(1L, List("c"))) //--> List(a, b)
println(m.getOrElse(2L, List("y"))) //--> List(y)
withDefault peut également être utilisé.
/** The same map with a given default function.
* Note: `get`, `contains`, `iterator`, `keys`, etc are not affected
* by `withDefault`.
*
* Invoking transformer methods (e.g. `map`) will not preserve the default value.
*
* @param d the function mapping keys to values, used for non-present keys
* @return a wrapper of the map with a default value
*/
def withDefault[B1 >: B](d: A => B1): immutable.Map[A, B1]
Exemple:
scala> def intToString(i: Int) = s"Integer $i"
intToString: (i: Int)String
scala> val x = Map[Int, String]().withDefault(intToString)
x: scala.collection.immutable.Map[Int,String] = Map()
scala> x(1)
res5: String = Integer 1
scala> x(2)
res6: String = Integer 2
J'espère que cela t'aides.