【发布时间】:2021-12-07 18:11:04
【问题描述】:
我正在寻找一种有效的方法来计算一个 JSON 文档是否是另一个 JSON 文档的子树/子集。
给定一个 JSON 文档 a
{
"a": {
"a": {"aa": ["uvw", "abc"]},
"b": {
"ba": {
"baa": ["none", "1"],
"bab": ["0"]
},
"bb": {
"baa": ["yyy"],
"bab": ["some_string"]
}
},
"c": {
"ca": ["dd", "cc"],
"cb": 2,
"cc": "-"
}
},
"e": "abc",
"d": 45678
}
还有一个 JSON 文档 b
{
"a": {
"a": {"aa": ["abc"]},
"b": {
"ba": {
"baa": ["none"],
"bab": ["0"]
},
"bb": {
"bab": ["some_string"]
}
},
"c": {
"ca": ["cc"]
}
},
"e": "abc"
}
我想确定b 是否是a 的子集
因此,我希望有一个布尔值(或类似 {'match': true} 的东西)表明 b 是 a 的子集。
我尝试了以下
.[0] as $a | .[1] as $b
| reduce ($a|paths) as $p (null; ($a|getpath($p)) as $va
| try($b|getpath($p)) as $vb
| if $va == $vb then setpath(["match"];true) else setpath(["match"];false) end)
但我错过了跟踪失败比较的方法。
如何使用jq 完成这种子树匹配?
提前感谢您的帮助!
【问题讨论】:
-
你能用文字定义你的意思吗?我会以完全不同的方式解释“子集”和“子树”,而且感觉都不完全准确。从您的示例的形状来看,我猜您想知道
b中的每个路径是否在a中都有一个匹配的路径,包含相同类型的实体,此外,如果该实体是标量,那么两者元素是否具有相同的值? -
好吧,不,我什至不认为这是您要问的...您认为
["a", "b", "c"]是["c", "b", "a"]的子集吗?["a", "a", "a"]是["a"]的子集吗?你如何比较复杂的数组成员?[{"red":1},{"green":1},{"blue":1}]是[{"red":1,"green":1,"blue":1}]的子集吗?这是一个棘手的问题,您需要精确地指定它。 -
@Jeremy - 您的文档
a不太正确:.a.b 下的第二个“ba”应该是“bb”。 -
@Weeble 感谢您指出这一点。实际上,我会考虑
["a", "b", "c"]和["c", "b", "a"]匹配。我认为["a", "a", "a"]不是["a"]的子集(但是,反向测试应该被认为是正确的)。我认为复杂的数组成员超出了这里的范围,尽管我正在寻找最通用的解决方案。 -
@peak 感谢您指出这一点。其实,这源于一点懈怠,对不起!现在已更正。