scalaplayframework-2.0playframework-json

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"?


Solution

  • 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
    }