我有许多非结构化json。例如:
{
"peoples": [
{
"name": "Vasya",
"age": 33
},
{
"name": "Petya",
"age": 40,
"childs": [
{
"name": "Vasya",
"age": 33
}
]
}
],
"notPeoples": [
{
"name": "Vasya",
"kind": "starship"
},
{
"name": "Iq441",
"kind": "car"
}
]
}
我需要删除所有对象,其中name = "Vasya"
。请注意,它可以是具有任何模式的json(不仅是人-某些对象具有“名称”字段的json),因此我应该分析每个对象(数组中的数组等)。
结果应为:
{
"peoples": [
{
"name": "Petya",
"age": 40,
"childs": []
}
],
"notPeoples": [
{
"name": "Iq441",
"kind": "car"
}
]
}
如何通过play json转换实现这一目标?也许还有另一个Java / scala库。
答案 0 :(得分:1)
该示例未生成您发布的确切JSON,但我想您已经知道如何使用play.json
过滤任意JSON:
def filterByName(name: String, filter: JsValue, js: JsValue): JsValue = js match {
case JsArray(vs) => JsArray(vs.map(filterByName(name, filter, _)))
case JsObject(vs) =>
JsObject(vs.flatMap { case (key, value) =>
if (key == name && value == filter) None
else Some(key -> filterByName(name, filter, value))
})
case otherwise => otherwise
}
def filterByString(name: String, value: String, js: JsValue): JsValue =
filterByName(name, JsString(value), js)
编辑: 如果我正确理解了您的用例,则可以实现如下所示的过滤器逻辑-上面的示例从输入JSON过滤单个元素,而该示例过滤“环绕”对象,以防其元素满足谓词:
def filterObjElements(name: String, value: JsValue, js: JsValue): JsValue = {
def filter(current: JsValue): Option[JsValue] = current match {
case JsArray(vs) => Some(JsArray(vs.flatMap(filter)))
case JsObject(vs) =>
if (vs.exists { case (key, value0) => key == name && value0 == value})
None
else {
Some(JsObject(vs.flatMap { case (key, value0) =>
filter(value0).map(key -> _)
}))
}
case otherwise => Some(otherwise)
}
js match {
case arr: JsArray => filter(arr).getOrElse(JsArray())
case obj: JsObject => filter(obj).getOrElse(JsObject(Nil))
case otherwise => otherwise
}
}
def filterObjElements(name: String, value: String, js: JsValue): JsValue =
filterObjElements(name, JsString(value), js)