在 JSON 格式化程序中将 Option[String] 映射到 Option[Int]
Map Option[String] to Option[Int] in JSON formatter
这是我的用例:
外部JSON
..
lat: "xx.xx",
lng: "xx.xx",
..
我的(工作)reader,原样:
..
(__ \ 'lat).read[Option[String]] ~
(__ \ 'lng).read[Option[String]] ~
..
我只想将 String
映射到 Int
。因为,从逻辑上讲,纬度和经度坐标应该这样表示。
这是我尝试过的方法,但没有用:
(__ \ 'lat).read[Option[String]].map(_.map(_.toInt) orElse None)) ~
我的案例 class 尝试执行上述操作时,否则它们 Option[String]
并且工作:
...
lat: Option[Int],
lng: Option[Int],
...
我认为问题可能只是语法上的问题,但是与括号的任何其他组合都无济于事。
编辑:
它编译,但是 JSON 不解析。它根本不构建我的对象。
如果我试试这个:
(__ \ 'lat).read[Option[String]].map(_.toInt)
我收到一个错误:
value toInt is not a member of Option[String]
但是在 REPL 中这是可行的:
val stringOpt: Option[String] = Some("10")
stringOpt.map(_.toInt)
res0: Option[Int] = Some(10)
调试 Reads
时,查看 validate[T]
可能发生的验证错误和异常很有帮助。您尚未发布案例 class,但反序列化格式为 xx.xx
至 Int
的字段没有任何意义。调用 "20.20".toInt
时你会得到一个 NumberFormatException
。 Double
可能更有意义,或者 BigDecimal
.
这个有效:
case class Location(lat: Option[Double], lon: Option[Double])
implicit val reads: Reads[Location] = (
(__ \ "lat").readNullable[String].map(_.map(_.toDouble)) and
(__ \ "lon").readNullable[String].map(_.map(_.toDouble))
)(Location.apply _)
当然,如果lat
或lon
不是数字,这会抛出异常。
处理此问题的最佳方法是根本不要将 JSON 中的数字格式化为字符串。然后 play-json 库将为您处理错误。如果这不可能,您可以考虑使用 Try
.
(__ \ "lat").readNullable[String].map(_.flatMap(x => Try(x.toDouble).map(Some(_)).getOrElse(None)))
这是我的用例:
外部JSON
..
lat: "xx.xx",
lng: "xx.xx",
..
我的(工作)reader,原样:
..
(__ \ 'lat).read[Option[String]] ~
(__ \ 'lng).read[Option[String]] ~
..
我只想将 String
映射到 Int
。因为,从逻辑上讲,纬度和经度坐标应该这样表示。
这是我尝试过的方法,但没有用:
(__ \ 'lat).read[Option[String]].map(_.map(_.toInt) orElse None)) ~
我的案例 class 尝试执行上述操作时,否则它们 Option[String]
并且工作:
...
lat: Option[Int],
lng: Option[Int],
...
我认为问题可能只是语法上的问题,但是与括号的任何其他组合都无济于事。
编辑:
它编译,但是 JSON 不解析。它根本不构建我的对象。
如果我试试这个:
(__ \ 'lat).read[Option[String]].map(_.toInt)
我收到一个错误:
value toInt is not a member of Option[String]
但是在 REPL 中这是可行的:
val stringOpt: Option[String] = Some("10")
stringOpt.map(_.toInt)
res0: Option[Int] = Some(10)
调试 Reads
时,查看 validate[T]
可能发生的验证错误和异常很有帮助。您尚未发布案例 class,但反序列化格式为 xx.xx
至 Int
的字段没有任何意义。调用 "20.20".toInt
时你会得到一个 NumberFormatException
。 Double
可能更有意义,或者 BigDecimal
.
这个有效:
case class Location(lat: Option[Double], lon: Option[Double])
implicit val reads: Reads[Location] = (
(__ \ "lat").readNullable[String].map(_.map(_.toDouble)) and
(__ \ "lon").readNullable[String].map(_.map(_.toDouble))
)(Location.apply _)
当然,如果lat
或lon
不是数字,这会抛出异常。
处理此问题的最佳方法是根本不要将 JSON 中的数字格式化为字符串。然后 play-json 库将为您处理错误。如果这不可能,您可以考虑使用 Try
.
(__ \ "lat").readNullable[String].map(_.flatMap(x => Try(x.toDouble).map(Some(_)).getOrElse(None)))