【发布时间】:2021-05-28 23:48:57
【问题描述】:
我在我的应用程序中使用 Gson 来解析 JSON。我有一个特殊的用例,我想获取一个 JsonObject 并有效地深度克隆它,除了更改与某些特定条件匹配的键/值。
例如,假设源对象是这样的:
{
"foo": {
"bar": {
"baz": "some value here"
},
"baz": "another value here"
}
}
我想遍历每个键(不管它是如何嵌套的),如果有一个名为 baz 的键,我将运行我的转换函数,我的输出对象将如下所示:
{
"foo": {
"bar": {
"bazTransformed": "this got altered by my function"
},
"bazTransformed": "so did this"
}
}
我知道我可以做一些事情,比如将 JsonObject 转换为字符串并使用 RegEx 模式来查找和替换,但这并不感觉正确。
我真的很难理解创建递归函数,或者至少是比字符串操作更好的解决方案。
我可以使用 编辑:
对我来说,最好将 JsonObject 转换为 Map ,如下所示:
我可以编写一个像这样递归迭代的函数:JsonObject.entrySet() 开始迭代,但这会返回一个 Mapgson.fromJson(sourceObj, Map::class.java) as MutableMap<*, *>fun generateObject(sourceObj: JsonElement): JsonObject {
val inputMap = gson.fromJson(sourceObj, Map::class.java) as MutableMap<*, *>
val outputMap: MutableMap<String, Any> = mutableMapOf()
fun go(toReturn: MutableMap<String,Any>,
input: MutableMap<String, Any>) {
for ((key, value) in input) {
if (key == "baz") {
println("baz key found")
//do my transformation here
}
if (value is Map<*, *>) {
println("nested map")
go(toReturn, value as MutableMap<String, Any>)
}
// this part is wrong however, because `key` is potentially nested
outputMap[key] = value
}
}
go(outputMap, inputMap as MutableMap<String, Any>)
return gson.toJsonTree(outputMap).asJsonObject
}
【问题讨论】:
-
您对
entrySet的建议很可能是实现这一点的最佳方式。 -
看看 JsonPath,一个解决这类问题的 DSL:stackoverflow.com/questions/27244431/…
-
感谢@fluffy - 我查看了 JsonPath,为了让它为我工作,我想我需要遍历树,在稍后传递给 JsonPath 时构造一个字符串路径。例如:
foo.bar.baz。但是,我在想,如果我已经能够递归地遍历每个节点,那么我应该能够构建一个我得到的对象(一个 Gson JsonObject,甚至是一个Map<*, *>,然后用 Gson 将它转换为一个 JsonObject .
标签: kotlin recursion functional-programming gson