从Array中的JSON对象中删除公共元素

时间:2015-04-10 13:47:11

标签: arrays json julia

我有一个对象数组,我希望从所有对象中常见的对象及其子对象中删除所有元素。

也许解释这个问题的最好方法是用一个例子

[
  {
    "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,但这并不符合我的要求。

1 个答案:

答案 0 :(得分:1)

我写了一些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)))