web-dev-qa-db-fra.com

Carte de filtrage pour les valeurs Aucune

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.

33
KChaloux

Comme chaque type de collection dans l'espace de noms scala.collection, une méthode Map a la méthode filter définie et Optiona la méthode isDefined, qui est true pour Some et false pour None. Vous pouvez filtrer les Nonevaleurs en combinant ces deux:

scala> map.filter(_._2.isDefined)
res4: scala.collection.immutable.Map[String,Option[Int]] = Map(one -> Some(1), two -> Some(2))
36
drexin

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)
51
Kristian Domagala

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})

6
ConorR