Un-optioning una opción opcionada


Digamos que tengo un val s: Option[Option[String]]. Por lo tanto, puede tener los siguientes valores:

Some(Some("foo")) Some(None) None

Quiero reducirlo para que el primero se convierta en Some("foo") mientras que los otros dos se conviertan en None. Obviamente hay muchas maneras de lograr esto, pero estoy buscando un simple, tal vez incorporado, menos de un trazador de líneas.

Author: Apocalisp, 2011-05-11

6 answers

Es una pena que flatten no exista. Debería.

Aplanar existe ahora.

Como antes,

s getOrElse None

(además de las otras respuestas) también hará lo mismo.

 35
Author: Rex Kerr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-21 21:06:59

Usted podría utilizar scalaz join para hacer esto, ya que esta es una de las operaciones monádicas:

doubleOpt.join

Aquí está en el REPL:

scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._

scala> some(some("X")).join
res0: Option[java.lang.String] = Some(X)

scala> some(none[String]).join
res1: Option[String] = None

scala> none[Option[String]].join
res3: Option[String] = None

Está disponible para cualquier cosa con una instancia de typeclass para una Mónada.

 16
Author: oxbow_lakes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-11 18:11:30
s.flatten

Seguido de un montón de caracteres para llegar al mínimo que stackoverflow permite

 12
Author: Dave Griffith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-11 17:50:36

Creo que la conversión al Iterable está bien. Utilice estos pasos para ir de Option[Option[String] a un solo Option[String]

s.flatten.headOption 

(que devuelve Option[String])

 4
Author: Dean Hiller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-02 19:15:25

Puede usar flatMap de la siguiente manera:

val options = List(Some(Some(1)), Some(None), None)
options map (_ flatMap (a => a))

Esto mapeará el List[Option[Option[Int]]] a un List[Option[Int]].
Si solo tiene una opción, puede usarla de la siguiente manera:

val option = Some(Some(2))
val unzippedOption = option flatMap (b => b)

Esto aplanará su Option[Option[Int]] a Option[Int].

 1
Author: tgr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-07 12:06:09

Bueno, en realidad no entiendo por qué podría ser simplemente Ninguno (el tercer caso). Si realmente puede ser también simplemente Ninguno, entonces votaría a favor de la respuesta de Rex Kerr, de lo contrario solo .obtener sería suficiente:

scala> Some(Some("foo")).get
res0: Some[java.lang.String] = Some(foo)

scala> Some(None).get
res1: None.type = None
 -4
Author: Antonin Brettsnajdr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-11 21:44:45