从数组中的 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)))