首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >scala upickle / ujson中JSON null的惯用处理

scala upickle / ujson中JSON null的惯用处理
EN

Stack Overflow用户
提问于 2021-04-05 18:19:26
回答 1查看 453关注 0票数 0

我是Scala新手,我想学习解决常见问题的惯用方法,就像Python中的pythonic语言一样。我的问题是使用皮克勒读取JSON数据,其中JSON值在出现时包含一个字符串,在不存在时为null。我希望使用自定义值来替换null。一个简单的例子:

代码语言:javascript
复制
import upickle.default._

val jsonString = """[{"always": "foo", "sometimes": "bar"}, {"always": "baz", "sometimes": null}]"""
val jsonData = ujson.read(jsonString)

for (m <- jsonData.arr) {
  println(m("always").str.length)  // this will work
  println(m("sometimes").str.length)  // this will fail, Exception in thread "main" ujson.Value$InvalidData: Expected ujson.Str (data: null)
}

问题在于字段"sometimes":当为null时,我们不能应用.str (或任何其他函数映射到除null以外的静态类型)。我正在寻找类似于m("sometimes").str("DEFAULT").length的东西,其中"DEFAULT"是null的替代品。

使用模式匹配的Idea 1,以下工作:

代码语言:javascript
复制
val sometimes = m("sometimes") match {
  case s: ujson.Str => s.str
  case _ => "DEFAULT"
}
println(sometimes.length)

考虑到Scala的简洁语法,这看起来有点复杂,当对许多值执行时将是重复的。

Idea 2回答相关问题的问题,创建一个带有默认值的case类。对于我的问题,当根据上下文需要不同的替换值时,创建case类对我来说似乎是不灵活的。

Idea 3另一个问题(不是只限于上床)讨论使用Try().getOrElse(),即:

代码语言:javascript
复制
import scala.util.Try
// ...
println(Try(m("sometimes").str).getOrElse("DEFAULT").length)

然而,讨论中提到,为常规程序路径抛出异常是很昂贵的。

什么是惯用的,但简洁的方法来解决这个问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-05 22:05:29

使用scala的选项实现这一目的的方法是惯用的或scala。

幸运的是,upickle值提供了它们。在strOpt源代码中参考方法。

代码中的问题是m(“始终”).str和m(“有时”).str中的str方法,这段代码过早地假定所有的值都是字符串。这就是strOpt方法出现的原因。如果它的值是字符串,则输出字符串;如果不是,则输出None类型。我们可以使用getOrElse方法,并结合它来决定如果值为None的话抛出什么。

以下是处理这一问题的最佳方法。

代码语言:javascript
复制
val jsonString = """[{"always": "foo", "sometimes": "bar"}, {"always": "baz", "sometimes": null}]"""

for (m <- jsonData.arr) {
    println(m("always").strOpt.getOrElse("").length)  
    println(m("sometimes").strOpt.getOrElse("").length) 
  } 

输出:

代码语言:javascript
复制
3
3
3
0

在这里,如果我们得到字符串以外的任何值(null,float,int),代码将输出为空字符串。它的长度将被计算为0。

基本上,这类似于您的"Idea1“方法,但这是scala的方法。而不是“默认”,我抛出一个空字符串,因为您不希望空值的长度为7(字符串长度“默认”)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66957772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档