如何用Circe解析对象数组?从指定JSON提取值转List[String]
使用Circe解析JSON并转换值列表的解决方案
我来帮你解决这个Circe解析JSON的问题,分两部分来说明:首先是提取值列表并转换为List[String],然后是解析对象数组的通用方法。
一、直接提取并转换值列表
首先,我们需要先确保引入了Circe的核心和解析库依赖(以SBT为例):
libraryDependencies ++= Seq( "io.circe" %% "circe-core" % "0.14.6", "io.circe" %% "circe-parser" % "0.14.6" )
针对你给出的JSON数据,我们可以通过手动导航JSON cursor的方式提取值并转换:
import io.circe._ import io.circe.parser._ // 你的JSON字符串 val jsonStr = """{ "field" : [ { "value" : 1.0 }, { "value" : 2.0 } ] }""" // 解析并转换的完整流程 val result: Either[Error, List[String]] = for { // 第一步:将字符串解析为Json对象 json <- parse(jsonStr) // 第二步:定位到"field"字段,转成Json对象列表 fieldArray <- json.hcursor.downField("field").as[List[Json]] // 第三步:遍历每个对象,提取"value"的Double值并转为String valueStrings <- fieldArray.traverse { obj => obj.hcursor.downField("value").as[Double].map(_.toString) } } yield valueStrings // 处理结果 result match { case Right(strList) => println(strList) // 输出: List(1.0, 2.0) case Left(error) => println(s"解析出错: ${error.getMessage}") }
这段代码的逻辑很清晰:
parse(jsonStr)负责把JSON字符串转成Circe的Json类型,返回Either[Error, Json]来处理解析失败的情况downField("field")通过cursor定位到目标字段,as[List[Json]]把字段值转成Json对象的列表traverse方法会遍历列表中的每个对象,提取value字段的Double值,再通过map把Double转为String,最后收集成List[String]
二、类型安全的对象数组解析
如果你的JSON结构固定,更推荐用case class映射+自动派生解码器的方式,这样代码更易维护且类型安全。
首先需要额外引入Circe的generic库:
libraryDependencies += "io.circe" %% "circe-generic" % "0.14.6"
然后定义和JSON结构对应的case class,并导入自动派生的解码器:
import io.circe._ import io.circe.parser._ import io.circe.generic.auto._ // 定义内层对象的case class case class ValueItem(value: Double) // 定义外层结构的case class case class FieldContainer(field: List[ValueItem]) val jsonStr = """{ "field" : [ { "value" : 1.0 }, { "value" : 2.0 } ] }""" // 直接解析为自定义类型 val parsedResult: Either[Error, FieldContainer] = decode[FieldContainer](jsonStr) parsedResult match { case Right(container) => // 提取值并转为List[String] val strList = container.field.map(_.value.toString) println(strList) // 输出: List(1.0, 2.0) case Left(error) => println(s"解析出错: ${error.getMessage}") }
这种方式的优势在于:
- 完全类型安全,编译器会帮你检查JSON结构和case class是否匹配
- 代码更简洁,不需要手动处理cursor导航
- 如果后续JSON结构有变化,只需要修改case class即可
额外小技巧
- 如果JSON中的
value字段可能为null或者不存在,可以把case class中的字段定义为Option[Double],避免解析失败 - 如果需要对转换后的String做格式化(比如保留两位小数),可以修改map逻辑:
_.value.formatted("%.2f")
内容的提问来源于stack exchange,提问作者nam
相关产品推荐
相关产品推荐

