Kotlin如何基于现有JsonObject覆盖指定键值生成新JsonObject
Kotlin 实现JsonObject指定键覆盖需求
核心思路
不需要硬套用fold操作,直接先复制原有JsonObject的全量内容,再遍历指定的key列表逐个判断替换即可,写法更清晰易维护。
以下按常用的JsonObject库分别给出实现:
方案1:Vert.x JsonObject(与你现有代码风格匹配)
import io.vertx.core.json.JsonObject // 需要校验更新的键列表 val updateKeys = listOf("service", "customerContact", "deliveryAddress", "deliveryZipCode", "deliveryZipArea", "deliveryCountryCode", "deliveryPhoneNumber") // 复制原有JsonObject数据,避免修改原对象 val newObject = existingData.copy() updateKeys.forEach { key -> // 满足两个条件则更新:1.order中存在该键 2.两个来源的值不匹配 if (order.containsKey(key) && existingData.getValue(key) != order[key]) { // 可按需调整赋值逻辑,比如转String后再赋值 newObject.put(key, order[key]) } }
方案2:fold写法(对齐JS reduce的实现逻辑)
如果你习惯类似JS reduce的迭代写法,也可以用Kotlin的fold实现,注意每次迭代需要返回累计对象:
val updateKeys = listOf("service", "customerContact", "deliveryAddress", "deliveryZipCode", "deliveryZipArea", "deliveryCountryCode", "deliveryPhoneNumber") val newObject = updateKeys.fold(existingData.copy()) { acc, key -> if (order.containsKey(key) && acc.getValue(key) != order[key]) { acc.put(key, order[key]) } acc // 必须返回当前累计的JsonObject }
方案3:kotlinx.serialization 不可变JsonObject实现
如果你用的是kotlin官方序列化库的不可变JsonObject,用buildJsonObject构造即可:
import kotlinx.serialization.json.* val updateKeys = listOf("service", "customerContact", "deliveryAddress", "deliveryZipCode", "deliveryZipArea", "deliveryCountryCode", "deliveryPhoneNumber") val newObject = buildJsonObject { // 先写入原有JsonObject的全部内容 putAll(existingData) updateKeys.forEach { key -> val orderValue = order[key] ?: return@forEach // 自定义值匹配逻辑,可按需调整 if (existingData[key]?.jsonPrimitive?.content != orderValue.toString()) { // 按值类型写入对应的Json元素 when(orderValue) { is String -> put(key, orderValue) is Number -> put(key, orderValue) is Boolean -> put(key, orderValue) // 其他复杂类型可自行补充转换逻辑 } } } }
注意事项
- 上述所有实现都不会修改原始的
existingData对象,所有修改都在新生成的对象上执行 - 等值判断逻辑可按你的业务需求替换为自定义的
matching比较规则 - 若
order中允许存在空值,可按需补充空值判断的分支逻辑
内容的提问来源于stack exchange,提问作者Leff
相关产品推荐
相关产品推荐

