J'ai cherché un peu, mais je n'ai pas encore trouvé de bonne réponse sur la façon de filtrer les entrées dans une carte dont la valeur est None. Disons que j'ai une carte comme celle-ci:
val map = Map[String, Option[Int]]("one" -> Some(1),
"two" -> Some(2),
"three" -> None)
J'aimerais finir par retourner une carte avec juste le ("one", Some(1))
et ("two", Some(2))
paire. Je comprends que cela se fait avec aplatir lorsque vous avez une liste, mais je ne sais pas comment obtenir l'effet sur une carte sans la diviser en clés et valeurs, puis en essayant de les rejoindre.
Comme chaque type de collection dans l'espace de noms scala.collection, une méthode Map
a la méthode filter
définie et Option
a la méthode isDefined
, qui est true
pour Some
et false
pour None
. Vous pouvez filtrer les None
valeurs en combinant ces deux:
scala> map.filter(_._2.isDefined)
res4: scala.collection.immutable.Map[String,Option[Int]] = Map(one -> Some(1), two -> Some(2))
Si vous filtrez les valeurs de None
, vous pourriez aussi bien extraire les valeurs de Some
en même temps pour vous retrouver avec un Map[String,Int]
:
scala> map.collect { case (key, Some(value)) => (key, value) }
res0: scala.collection.immutable.Map[String,Int] = Map(one -> 1, two -> 2)
Aussi map.filterKeys( map(_) != None)
ou
for( (k,v) <- map if( v!= None)) yield (k,v)
Cette approche fournit une méthode filterValues générale qui n'existe pas sur les cartes.
Une telle méthode me manque, car aucune des alternatives n'est parfaite.
[Mis à jour plus tard] Il s'agit d'une meilleure version qui ne fait pas de recherche sur chaque entrée et qui lit toujours assez clairement.
map.filter( {case (x,y)=> y!=None})