【问题标题】:How to use Hcursor or Optics, as part of Circe-Json, to return a List of matching Objects?作为 Circe-Json 的一部分,如何使用 Hcursor 或 Optics 返回匹配对象列表?
【发布时间】:2019-05-19 00:54:54
【问题描述】:

我的代码大致如下:

val json: Json = parse("""
[
{
"id": 1,
"type": "Contacts",
"admin": false,
"cookies": 3
},
{
"id": 2,
"type": "Apples",
"admin": false,
"cookies": 6
},
{
"id": 3,
"type": "Contacts",
"admin": true,
"cookies": 19
}
]
""").getOrElse(Json.Null)

我正在使用 Circe、Cats、Scala、Circe-json 等,Parse 调用成功。

我想返回一个列表,其中 type="Contacts" 的每个顶级对象都完整显示。

类似: List[String] = ["{"id": 1,"type": "Contacts","admin": false,"cookies": 3}","{"id": 3,"type": "Contacts ","admin": true,"cookies": 19}"]

背景是我在磁盘上有大型 JSON 文件。我需要过滤掉与某个type= 值匹配的对象子集,在本例中为type=Contacts,然后将它们从json 文件的其余部分中拆分出来。我不打算修改文件,我更希望 grep 匹配对象并相应地处理它们。

谢谢。

【问题讨论】:

    标签: json scala circe


    【解决方案1】:

    完成这种事情的最直接方法是将文档解码为List[Json]List[JsonObject] 值。例如,给定您对json 的定义:

    import io.circe.JsonObject
    
    val Right(docs) = json.as[List[JsonObject]]
    

    然后就可以根据type查询:

    scala> val contacts = docs.filter(_("type").contains(Json.fromString("Contacts")))
    contacts: List[io.circe.JsonObject] = List(object[id -> 1,type -> "Contacts",admin -> false,cookies -> 3], object[id -> 3,type -> "Contacts",admin -> true,cookies -> 19])
    
    scala> contacts.map(Json.fromJsonObject).map(_.noSpaces).foreach(println)
    {"id":1,"type":"Contacts","admin":false,"cookies":3}
    {"id":3,"type":"Contacts","admin":true,"cookies":19}
    

    鉴于您的用例,circe-optics 似乎不太适合(请参阅 my answer here,了解为什么 Monocle 的 Traversal 使用任意谓词进行过滤会很尴尬)。

    如果您有兴趣在不将文件的全部内容加载到内存中的情况下解析和过滤大型 JSON 文件,则可能值得研究 circe-fs2 或 circe-iteratee。在这两种情况下,原理都与上面的 List[JsonObject] 代码相同——您将大型 JSON 数组解码为 JsonObject 值流,您可以随意查询。

    【讨论】:

      猜你喜欢
      • 2018-10-06
      • 2019-08-16
      • 2015-10-23
      • 1970-01-01
      • 2020-02-19
      • 2022-01-13
      • 1970-01-01
      • 2014-03-09
      • 2023-04-08
      相关资源
      最近更新 更多