从数组中的 JSON 个对象中删除公共元素
Remove common elements from JSON Objects in Array
我有一个对象数组,我希望从对象及其子对象中删除所有对象中共有的所有元素。
也许最好的解释方法是举个例子
[
{
"a": {
"k1": [1,2,3],
"k2": 4
},
"b": {
"k3": {
"foo": "bar",
"top": "bottom"
},
"k4": 5
},
"c": {
"k5": [{"cat":"dog"},{"rat":"not rat"}]
},
"d": { }
},
{
"a": {
"k1": [1,2,3],
"k2": -4
},
"b": {
"k3": {
"foo": "hat",
"top": "bottom"
},
"k4": 5
},
"c": {
"k5": [{"cat":"dog"},{"rat":"mouse"}]
}
}
]
计算结果为
[
{
"a": {
"k2": 4
},
"b": {
"k3": {
"foo": "bar"
}
},
"c": {
"k5": [{"cat":"dog"},{"rat":"not rat"}]
},
"d": { }
},
{
"a": {
"k2": -4
},
"b": {
"k3": {
"foo": "hat"
}
},
"c": {
"k5": [{"cat":"dog"},{"rat":"mouse"}]
},
"d": null
}
]
有什么好的工具可以解决这个问题吗?我查看了 json-diff,但这不太符合我的要求。
我写了一些 julia 函数来帮我做这件事
我首先计算对象中的公共字段,然后从每个对象中删除公共字段。
function common_in_array(a::Array)
common = deepcopy(a[end])
common_in_array!(a[1:end-1], common)
end
function common_in_array!(a::Array, common::Dict)
if size(a,1) == 0
return common
else
return common_in_array!(a[1:end-1], dict_common!(a[end], common))
end
end
function dict_common!(d::Dict, common::Dict)
keys_d = keys(d)
keys_common = keys(common)
all_keys = union(keys_d, keys_common)
and_keys = intersect(keys_d, keys_common)
for k in setdiff(all_keys, and_keys)
delete!(common, k)
end
for k in and_keys
v1 = d[k]
v2 = common[k]
if typeof(v1) != typeof(v2)
delete!(common, k)
elseif isa(v2, Dict)
dict_common!(v1, v2)
elseif v1 != v2
delete!(common, k)
end
end
common
end
function remove_common_from_dict!(d::Dict, common::Dict)
for (key, value) in common
if key in keys(d)
value_d = d[key]
if value == value_d
delete!(d, key)
elseif isa(value, Dict) && isa(value_d, Dict)
remove_common_from_dict!(value_d, value)
end
end
end
d
end
function remove_common_from_array!(a::Array, common::Dict)
map(d -> remove_common_from_dict!(d, common), a)
end
function remove_common_from_array!(a::Array)
remove_common_from_array!(a, common_in_array(a))
end
然后我在 json_array
字符串
上对其进行评估
using JSON
JSON.print(remove_common_from_array!(JSON.parse(json_array)))
我有一个对象数组,我希望从对象及其子对象中删除所有对象中共有的所有元素。
也许最好的解释方法是举个例子
[
{
"a": {
"k1": [1,2,3],
"k2": 4
},
"b": {
"k3": {
"foo": "bar",
"top": "bottom"
},
"k4": 5
},
"c": {
"k5": [{"cat":"dog"},{"rat":"not rat"}]
},
"d": { }
},
{
"a": {
"k1": [1,2,3],
"k2": -4
},
"b": {
"k3": {
"foo": "hat",
"top": "bottom"
},
"k4": 5
},
"c": {
"k5": [{"cat":"dog"},{"rat":"mouse"}]
}
}
]
计算结果为
[
{
"a": {
"k2": 4
},
"b": {
"k3": {
"foo": "bar"
}
},
"c": {
"k5": [{"cat":"dog"},{"rat":"not rat"}]
},
"d": { }
},
{
"a": {
"k2": -4
},
"b": {
"k3": {
"foo": "hat"
}
},
"c": {
"k5": [{"cat":"dog"},{"rat":"mouse"}]
},
"d": null
}
]
有什么好的工具可以解决这个问题吗?我查看了 json-diff,但这不太符合我的要求。
我写了一些 julia 函数来帮我做这件事
我首先计算对象中的公共字段,然后从每个对象中删除公共字段。
function common_in_array(a::Array)
common = deepcopy(a[end])
common_in_array!(a[1:end-1], common)
end
function common_in_array!(a::Array, common::Dict)
if size(a,1) == 0
return common
else
return common_in_array!(a[1:end-1], dict_common!(a[end], common))
end
end
function dict_common!(d::Dict, common::Dict)
keys_d = keys(d)
keys_common = keys(common)
all_keys = union(keys_d, keys_common)
and_keys = intersect(keys_d, keys_common)
for k in setdiff(all_keys, and_keys)
delete!(common, k)
end
for k in and_keys
v1 = d[k]
v2 = common[k]
if typeof(v1) != typeof(v2)
delete!(common, k)
elseif isa(v2, Dict)
dict_common!(v1, v2)
elseif v1 != v2
delete!(common, k)
end
end
common
end
function remove_common_from_dict!(d::Dict, common::Dict)
for (key, value) in common
if key in keys(d)
value_d = d[key]
if value == value_d
delete!(d, key)
elseif isa(value, Dict) && isa(value_d, Dict)
remove_common_from_dict!(value_d, value)
end
end
end
d
end
function remove_common_from_array!(a::Array, common::Dict)
map(d -> remove_common_from_dict!(d, common), a)
end
function remove_common_from_array!(a::Array)
remove_common_from_array!(a, common_in_array(a))
end
然后我在 json_array
字符串
using JSON
JSON.print(remove_common_from_array!(JSON.parse(json_array)))