【问题标题】:Scala, Circe - how to check if json contains keys with different values?Scala,Circe - 如何检查 json 是否包含具有不同值的键?
【发布时间】:2021-08-20 18:22:14
【问题描述】:

我有一个包含类似字段的 json:

{
  "newData": {
    "data": {
      "field1": "value1",
      "field2": value2,
      "field3": "value3"
    }
  }
  "oldData" :{
    "data": {
      "field1": "value1",
      "field3": "someValue"
    }
  }
}

现在我想比较 newDataoldData。如果newData 包含一些不在oldData 中的新字段,我想将它们添加到Set。此外,如果newDataoldData 具有相同的字段,但具有不同的值,我也想将它们添加到Set。如果它们相同,我想忽略。

我尝试像这样使用circe

val newData = json.newData
val oldData = json.oldData
val result = newData.hcursor.keys.toSet
.filterNot(oldData.hcursor.keys.toSet)

如果newData 有一些其他字段然后oldData 也可以。但是,如果它们都具有具有其他值的相同字段,则它不起作用。我不知道如何比较两个 json 中相同键的值,如果它们不同,请将它们添加到设置中。 我应该如何更改我的代码以包含它?

【问题讨论】:

    标签: json scala scala-cats circe


    【解决方案1】:

    您可以确保两者都是JsonObjects,然后选择新记录的所有键并检查该键是否存在于旧记录中,如果确实存在则确保其内容不同。

    import io.circe.JsonObject
    
    def findFieldsWithDifferences(oldData: JsonObject, newData: JsonObject): Set[String] =
      newData.toList.collect {
        case (newKey, newValue) if oldData(key = newKey).forall(_ != newValue) =>
          newKey
      }.toSet
    

    可以看到运行here的代码

    【讨论】:

    • 是的,我将 json 解析为 scala 对象。现在我想检查newData 中的数据是否存在于oldData 中,如果不存在则将其添加到Set。如果两者都存在相同的字段但具有不同的值,则相同。
    • @Developus 不正是我的代码所做的吗?或者我错过了什么?
    • 问题是newDataoldData 大约是Json。我不能打电话给toList。这就是为什么在我的示例中我需要查看键。
    • @Developus 是的,只需使用 JsonObject 而不是 Json 就像在我链接的 Scastie 中一样。
    • @Developus “是否有可能只使用 Json 类型做同样的事情” 不是真的,因为键是一个仅适用于 JsonObjects 的概念,不适用于任何任意 Json 值。 - 其次,为什么你不能从Json 更改为JsonObject,如果你是从String 读取数据,你只需要像Scastie 所示调整解码器 -最后,如果您确实无法将数据读取为JsonObject,那么您可以使用返回Option[JsonObject]Json.asObject 方法;检查API
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-06
    • 1970-01-01
    • 2015-03-28
    • 2022-01-15
    • 1970-01-01
    相关资源
    最近更新 更多