Valentin Tihomirov
Valentin Tihomirov

Reputation: 1

How do you convert option to None?

Consider example

object Main extends App {
  case class ref(val target: Object)
  val map: Map[Int, ref] = Map(1 -> ref(null), 2 -> ref("2")) 
                                            //> map  : Map[Int,o.ref] = Map(1 -> ref(null), 2 -> ref(2))

  def request(id: Int, default: Object) = {
    println(map.get(id) map (_.target) match {
      case Some(result) => result
      case None => default
    })
  }                                         //> request: (id: Int, default: Object)Unit
  request(0, "fixed 0")                     //> fixed 0
  request(1, "fixed 1")                     //> null
  request(2, "fixed 2")                     //> 2
}

As you see, option1 results in null. I want such targets to handle likewise there is no match in the db. How do I convert Some(null) to None?

Upvotes: 2

Views: 1755

Answers (4)

marstran
marstran

Reputation: 28056

Calling map.get(1) will return Some(ref(null)). Doing Some(ref(null)) map (_.target) results in Some(null). That is why you get null. You could do this instead:

def request(id: Int, default: Object) = {
    println(map.get(id).flatMap(r => Option(r.target)).getOrElse(default))
}

Now request(1, "fixed 1") will print fixed 1.

Also, your final match expression can be shortened to getOrElse(default).

Upvotes: 0

Zoltán
Zoltán

Reputation: 22206

In general, if you want to convert a value that may be null into an Option, just build it like so:

Option(ref)

In your case, since you want an inner field to become an Option, you can just flatMap:

map.get(id).flatMap(ref => Option(ref.target))

I would rewrite your request method so:

def request(id: Int, default: Object) =
  println(map.get(id).flatMap(ref => Option(ref.target)).getOrElse(default))

Option's apply method does exactly what you want, if you pass it a null, it will return a None, that's how the flatMap bit works.

Upvotes: 2

Lee
Lee

Reputation: 144206

You can use filter:

map (_.target) filter (_ != null)

Upvotes: 3

Valentin Tihomirov
Valentin Tihomirov

Reputation: 1

Up do date, my best match was to use flatMap

map (_.target) flatMap { case null => None ; case a => Some(a) } 

Upvotes: 1

Related Questions