Nate
Nate

Reputation: 12819

Concise way of mapping null result of Option

Say I have some class B and some class A that I do not control:

class B
class A { def getB: B = ... }

Sometimes the result of getB is a valid B, and sometimes it is null. I have an optional A that I want to get an optional B out of. This is the "simplest" way I could figure out how to do it:

val a: Option[A] = ...
val b: Option[B] = a flatMap {x => Option(x.getB)}

I wanted to get rid of the named x, so I tried this, which isn't simpler:

val b: Option[B] = a map {_.getB} flatMap Option.apply

I tried composing _.getB with Option, and the only other thing I got to work was less simple:

val b: Option[B] = a flatMap {((x: A) => x.getB) andThen Option.apply _}

What is a simpler way? This seems like it would be a common enough problem that there is an elegant solution. What I would really like to have is something close to this, which is obviously not possible:

val b: Option[B] = a flatMap {Option(_.getB)}

Upvotes: 1

Views: 130

Answers (1)

Eric
Eric

Reputation: 1114

There's no way to make it more concise in-line, but you could use the "enrich my library" pattern to add your own functionality to A, such as a method called safeGetB that does what you want:

scala> :pa
// Entering paste mode (ctrl-D to finish)

class B
class A {
  def getB: B = null
}

implicit class RichA(a: A) {
  def safeGetB: Option[B] = Option(a.getB)
}

Some(new A()).flatMap(_.safeGetB)

// Exiting paste mode, now interpreting.

defined class B
defined class A
defined class RichA
res0: Option[B] = None

Upvotes: 6

Related Questions