2012-06-26 10 views
8

A veces deseo devolver el valor que es una propiedad de un objeto envuelto en la opción, pero no puedo hacerlo fácilmente con getValue.orElse(otherValue).¿Sintaxis de Scala para acceder a la propiedad de una opción en línea y encadenar "OrElse"?

Por ejemplo, estoy mapeando propiedades en línea y quiero usar un patrón como object.get.property.orElse(""). Pero lo anterior no compila. ¿Cómo puedo acceder a esa propiedad y aún mantener una sintaxis similar a la de las opciones?

Respuesta

12

Puede utilizar map() para lograrlo. Se hace evidente una vez que comience a pensar en Option[T] como un contenedor de tipo T que puede contener 0 o 1 elemento:

case class Person(name: String, age: Int) 

val optionalPerson = Some(Person("John", 29)) 
val name = optionalPerson map {_.name} getOrElse "?" 

Por otra parte, si usted tiene una estructura anidada de Option s:

case class Person(name: String, age: Int, parent: Option[Person]) 

se puede extraer anidada Option con flatMap:

val optionalPerson = Some(Person("John", 29, Some(Person("Mary", 55, None)))) 
val parentName = optionalPerson flatMap {_.parent} map {_.name} getOrElse "Unknown parent name" //Mary 

O puede utilizar filter() para activar Some() en None cuando el valor envuelto en Some no satisface algunos criterios:

val nameIfAdult = optionalPerson filter {_.age >= 18} map {_.name} 
+0

Bueno, yo thought'd que había puesto un poco de conocimiento, pero puedo ver que tomó mi respuesta a un nivel completamente nuevo. Dulce... – crockpotveggies

4

Utilice map() para mantener el patrón en forma de opción. Por ejemplo, debe obtener la propiedad name de un objeto field. Pero si el campo es realmente None, puede devolver una cadena en blanco. De esta manera:

field.map(_.name).getOrElse("")

Y su uso en el cuadro más grande:

implicit def castDraftModel(drafts:List[Tuple2[models.ReportInstance,Option[models.Report]]]) = drafts.map{ 
    (field) => 
     List(Field(
     field._1.id, 
     field._1.teamId, 
     field._2.map(_.name).getOrElse(""), 
     field._1.lastModifiedRelative, 
     field._2.map(_.id).getOrElse(0L), 
     field._2.map(_.reportType).getOrElse(""), 
     field._1.referenceId, 
     field._1.referenceName(draft._2.map(_.reportType).getOrElse("")))) 
    }.flatten.sortBy(_.id) 
Cuestiones relacionadas