Sometimes I want to return the value that is a property of an object wrapped in option, but I can't do that easily with getValue.orElse(otherValue)
.
For instance, I am mapping properties inline and I want to use a pattern like object.get.property.orElse("")
. But the preceding doesn't compile. How can I access that property and still maintain an option-like syntax?
You can use map()
to achieve this. It becomes obvious once you start to think about Option[T]
like a container of type T
that can hold 0 or 1 element:
case class Person(name: String, age: Int)
val optionalPerson = Some(Person("John", 29))
val name = optionalPerson map {_.name} getOrElse "?"
Furthermore if you have a nested structure of Option
s:
case class Person(name: String, age: Int, parent: Option[Person])
you can extract nested Option
with flatMap
:
val optionalPerson = Some(Person("John", 29, Some(Person("Mary", 55, None))))
val parentName = optionalPerson flatMap {_.parent} map {_.name} getOrElse "Unknown parent name" //Mary
Or you can use filter()
to turn Some()
into None
when value wrapped in Some
does not satisfy some criteria:
val nameIfAdult = optionalPerson filter {_.age >= 18} map {_.name}
Use map()
to maintain the option-like pattern.
For instance you need to get the name
property of a field
object. But if field is actually None
, you can return a blank string. Like this:
field.map(_.name).getOrElse("")
And using it in the bigger picture:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With