2015-09-15 10 views
5

Ich habe eine Map[A, Option[B]], was ist der optimale Weg, um eine Abflachung zu machen, um eine Map[A, B] zu bekommen?Eine Karte von Option zu Karte abflachen

ich für eine Liste wissen wir abflachen können, aber diese Struktur ist anders

Antwort

13

Nun, sie sind nicht die gleichen, so dass Sie einen Weg brauchen, um zu definieren, was passiert, wenn ein Wert Keiner ist. Ich nehme an, Sie diese Schlüssel zu ignorieren, wenn ja, Sie mit einer Teilfunktion sammeln können:

map.collect { 
    case (k, Some(v)) => k -> v 
} 

oder verwenden Sie ein für Verständnis

for ((k, Some(v)) <- map) yield k -> v 
+0

ja ich habe nicht präzisiert, dass ich keinen schlüssel mit Kein wert wünsche, vielen dank für ihre antwort! – nam

+1

eigentlich 'für ((k, Einige (v)) <- Karte) Ausbeute k -> v 'ist genug – dk14

+0

sehr wahr! Ich werde aktualisieren! Passte das Muster oben und nicht darunter, Idiot ... –

1

Wenn Sie nicht doppelt Iteration nichts dagegen:

map.filter(_._2.nonEmpty).mapValues(_.get) 

Beispiel:

scala> Map(1 -> Some(1), 2 -> None).filter(_._2.nonEmpty).mapValues(_.get) 
res9: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1) 

oder die Nutzung dieser impliziten:

implicit def flat[K,V](kv: (K, Option[V])) = kv._2.map(kv._1 -> _).toList 

Dann:

map.flatten.toMap 

oder ohne Verwendung (möglicherweise unsicheren) implizite:

map flatMap flat 

Beispiel:

scala> Map(1 -> Some(1), 2 -> None).flatten.toMap 
res2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1) 

scala> def flat[K,V](kv: (K, Option[V])) = kv._2.map(kv._1 -> _).toList 
warning: there was one feature warning; re-run with -feature for details 
flat: [K, V](kv: (K, Option[V]))List[(K, V)] 

scala> Map(1 -> Option(1), 2 -> None).flatMap(flat) 
res29: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1) 
+0

Es lohnt sich zu beachten, dass 'mapValues' eine Ansicht auf der Karte zurückgibt, was wahrscheinlich nicht das ist, was das OP will. – jhn

+0

@jhn hängt davon ab, ob Code in mapValues ​​referenziell-transparent ist, wie in meiner Antwort, warum sollte sich jemand darum kümmern? Für Java-Serialisierung (wenn man es immer noch aus irgendeinem Grund verwendet), gibt es immer .view.force oder .map (Identität) – dk14

+0

Warum sollte jemand kümmern? Performance. – jhn