Zuriar
Zuriar

Reputation: 11734

Filter a string before creating an Option[String]

I have the following where obj is a JsObject:

val approx_pieces: Option[String] = (obj \ "approx_pieces").asOpt[String]

This code will create a Some("0") if the approx pieces is "0" in the database.

How can I change it so that it creates None when the string is "0"?

Upvotes: 3

Views: 388

Answers (1)

Ben Reich
Ben Reich

Reputation: 16324

If you already have an Option, and you don't want to use the value in certain cases, then filter is your most idiomatic choice:

val one = Option("1")
val zero = Option("0")
one.filter(_ != "0") //Some("1")
zero.filter(_ != "0") //None

Using this method, your solution would be:

(obj \ "approx_pieces").asOpt[String].filter(_ != "0")

Alternatively, you can do this with a match statement. The JsValue subtypes in Play all have an unapply method, so you can directly match on them:

(obj \ "approx_pieces") match {
    case JsString(num) if num != "0" => Some(num)
    case _ => None
}

You might also be interested in the collect method:

(obj \ "approx_pieces").asOpt[String] collect {
    case num if num != "0" => num
}

collect is nice because it allows you to filter and map at the same time.

You can use both of the above methods together, too:

Option(obj \ "approx_pieces") collect {
    case JsString(num) if num != "0" => num
}

Upvotes: 8

Related Questions