json - 作为 Circe-Json 的一部分,如何使用 Hcursor 或 Optics 返回匹配对象列表?
问题描述
我的代码大致如下所示:
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" : "联系人","admin": true,"cookies": 19}"]
背景是我在磁盘上有大型 JSON 文件。我需要过滤掉与某个type=
值匹配的对象子集,在本例中为type=Contacts
,然后将它们从 json 文件的其余部分中拆分出来。我不想修改文件,我更希望 grep 匹配对象并相应地处理它们。
谢谢你。
解决方案
完成这类事情最直接的方法是将文档解码为 aList[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 似乎不太适合(请参阅我的回答,了解为什么使用任意谓词进行过滤与 Monocle's 尴尬Traversal
)。
但是,如果您有兴趣解析和过滤大型 JSON 文件而不将文件的全部内容加载到内存中,那么可能值得研究 circe-fs2 或 circe-iteratee。在这两种情况下,原理都与上面的代码相同List[JsonObject]
——您将大 JSON 数组解码为JsonObject
值流,您可以随意查询。
推荐阅读
- python - 从日期时间戳获取开始和结束时间
- database - 何时拆分到另一个数据库表
- java - 如何将 A* 算法的结果用于 2D 游戏?
- google-bigquery - 将数据流式传输到 Google BigQuery 表中:SocketTimeoutException、502 Bad Gateway、500 Internal Server Error 警告
- sql - 如何使用指向一个表的多个外键进行查询?
- r - 使用 strptime() 函数将日期转换为 R 中的时间戳
- swift - Swift UISearchbar如何搜索类的属性
- c++ - NTP时间戳未正确解析c ++
- assembly - Irvine 书中的这个 SWORD 零扩展示例真的正确吗?
- css - 如果它不适合,防止 div 跳转到下一行