我想比较两个json文件,看看是否可以从另一个中提取一个
P1(p1.json)
{
"id": 12,
"keys": ["key1","key2"],
"body": {
"height": "180cm",
"wight": "70kg"
},
"name": "Alex"
}
P2(p2.json)
{
"id": 12,
"keys": ["key2","key1"],
"body": {
"height": "180cm"
}
}
可以看出 P2 并不完全等于 P1 ,但可以从 P1 中提取(它提供的数据较少同一个人,但数据是正确的)。
预期行为:
p1 extends p2 --> true
p2 extends p1 --> false
备注
- 无法使用一些其他元素从同一数组中提取数组
答案 0 :(得分:2)
extends/1
的以下定义使用纯粹基于对象的扩展定义(特别是,它不对数组进行排序)。关于数组的OP要求对我来说不清楚,但在下一节中提供了变体定义。
# Usage: $in | extends($b) iff $in contains $b in an object-based sense
def extends($b):
# Handle the case that both are objects:
def objextends($x):
. as $in | all($x|keys[]; . as $k | $in[$k] | extends($x[$k]));
# Handle the case that both are arrays:
def arrayextends($x):
. as $in
| length == ($x|length) and
all( range(0;length); . as $i | $in[$i] | extends($x[$i]));
if . == $b then true
else . as $in
| type as $intype
| ($intype == ($b|type)) and
(($intype == "object" and objextends($b)) or
($intype == "array" and arrayextends($b)))
端;
示例:
{a:{a:1,b:2}, b:2} | extends({a:{a:1}}) # true
{a:{a:1,b:2}, b:2} | extends({a:{a:2}}) # false
{a:{a:1,b:2}, b:[{x:1,y:2}]} | extends({a:{a:2}, b:[{x:1}]}) # true
以下定义对数组进行排序,并且足以处理给定的示例:
# Usage: $in | extends2($b) iff $in contains $b in a way which ignores the order of array elements
def extends2($b):
# Both are objects
def objextends($x):
. as $in | all($x|keys[]; . as $k | $in[$k] | extends($x[$k]));
def arrayextends($x): ($x|sort) - sort == [];
if . == $b then true
else . as $in
| type as $intype
| ($intype == ($b|type)) and
(($intype == "object" and objextends($b)) or
($intype == "array" and arrayextends($b)))
end;
显示$ P1和$ P2:
$P1 | extends2($P2) # yields true
答案 1 :(得分:0)
如果您知道任何子阵列中没有重复项,那么您可以使用此方法计算从tostream返回的[path,value]
对的集合之间的差异,用null
替换数组索引:< / p>
def details:[
tostream
| select(length==2) as [$p,$v]
| [$p|map(if type=="number" then null else . end),$v]
];
def extends(a;b): (b|details) - (a|details) == [];
如果P1
和P2
是返回样本数据的函数
def P1: {
"id": 12,
"keys": ["key1","key2"],
"body": {
"height": "180cm",
"wight": "70kg"
},
"name": "Alex"
}
;
def P2: {
"id": 12,
"keys": ["key2","key1"],
"body": {
"height": "180cm"
}
}
;
然后
extends(P1;P2) # returns true
, extends(P2;P1) # returns false
在存在重复的情况下,结果不太清楚。 e.g。
extends(["a","b","b"];["a","a","b"]) # returns true