Scala,Circe-如何检查json是否包含具有不同值的键?

Scala,Circe-如何检查json是否包含具有不同值的键?,json,scala,scala-cats,circe,Json,Scala,Scala Cats,Circe,我有一个json,其中包括类似的字段: { "newData": { "data": { "field1": "value1", "field2": value2, "field3": "value3" } } "oldData" :{ "data"

我有一个json,其中包括类似的字段:

{
  "newData": {
    "data": {
      "field1": "value1",
      "field2": value2,
      "field3": "value3"
    }
  }
  "oldData" :{
    "data": {
      "field1": "value1",
      "field3": "someValue"
    }
  }
}
现在我想比较一下
newData
oldData
。如果
newData
包含一些不在
oldData
中的新字段,我想将它们添加到
集合中。另外,如果
newData
oldData
具有相同的字段,但具有不同的值,我还希望将它们添加到
Set
。如果它们是相同的,我想忽略它们

我试着用
circe
这样做:

val newData = json.newData
val oldData = json.oldData
val result = newData.hcursor.keys.toSet
.filterNot(oldData.hcursor.keys.toSet)
如果
newData
有一些其他字段,然后
oldData
就可以了。但是,如果这两个字段都具有相同的字段和其他值,则不起作用。我不知道如何比较两个JSON中相同键的值,如果它们不同,则将它们添加到集合中。
我应该如何更改代码以包含它?

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

导入io.circe.JsonObject
def findFieldsWithDifferences(旧数据:JsonObject,新数据:JsonObject):设置[字符串]=
newData.toList.collect{
如果oldData(key=newKey),则为case(newKey,newValue)。forall(!=newValue)=>
纽基
}.托塞特


您可以看到代码正在运行。

是的,我将json解析为scala对象。现在我想检查
newData
中的数据是否存在于
oldData
中,如果不存在,则将其添加到
Set
。如果两个字段中都存在相同的字段,但有不同的值,这是一样的。@Developus这不正是我的代码所做的吗?或者我遗漏了什么?问题是
newData
oldData
是circe
Json
。我不能在上面调用
toList
。这就是为什么在我的示例中我需要查看键的原因。@Developus是的,只使用
JsonObject
,而不是像我链接的Scastie中那样使用
Json
。@Developus“是否可以只使用Json类型做同样的事情”不太可能,因为键是一个只适用于
JsonObjects
,而不是任何任意的Json值的概念其次,为什么不能从
Json
更改为
JsonObject
,如果要从
字符串中读取数据,只需调整解码器,如Scastie中所示-最后,如果确实无法将数据作为
JsonObject
读取,则可以使用
Json.asObject
方法返回
选项[JsonObject]
;检查一下。