immrsteel
immrsteel

Reputation: 1495

compare two json objects and remove the element and then compare resultant json to other json file

Python newbie:

Default.json

   {
"name": {
 "provide": ""
},
"test": {
  "Fail": {
    "centers": None,
    "Nearest": 0
  },
  "far": "",
  "Meta": null,
  "Only": false,
  "Tags": null
 },
"Session": "",
"conf": {
  "check": "",
  "Reg": ""
 },
"Token": "" 

}

Remote.json

 [ {
  'name': {
  'provide': ''
   },
  'Name': 'abc',
  'test': {
    'Service': 'redis',
    'Tags': [
      'stage'
     ],
    'Fail': {
      'centers': None,
      'Nearest': 3
     },
     'Only': false,
     'far': '',
     'Meta': null
    },
   'Token': '',
   'Session': '',

   'conf': {
     'Reg': '',
     'check': 'name_prefix_match'
    },
} ]

I have a default.json and remote .json .Task I am trying to achieve is remove all the json elements from the remote.json for whom the values of remote.json matches with the default.json.For example since the key,value of name:{provider=""} from default.json matches the name:{provider=""} from remote.json.It should get removed from remote.json

with open(remote.json) as f:
 with open(default.json) as m:
   file=json.load(f)
   default=json.load(m)
   for i in xrange(len(file)):
     for key,value in default.items():
        #default[key]=value
      #a=filter(lambda x: x[""],file.keys())

1.I am not getting the idea here how to get key, value from default and compare it with file?Any help would be appreciated.

The reason I need to remove element from remote.json is because I need to compare the resultant json with other json file "local.json".If i dont' remove the key ,values with value "" or null or None then the comparison between remote.json and local.json would never be equal.

2.Is there any better way of going for this problem?

local.json

{ 
  "Name": "",
  "conf": {
   "check": "name_prefix_match",
  },
  "test": {
    "Service": "redis",
    "Fail": {
     "Near": 3
   },
  "Tags": ""
  }
}

Upvotes: 0

Views: 2667

Answers (1)

Azat Ibrakov
Azat Ibrakov

Reputation: 10962

There are some problems with JSON examples because of None & False are not valid JSON objects (and so are single-quoted string literals), so let's pretend that we've already parsed files and got something like

default_json = {
    "name": {
        "provide": ""
    },
    "test": {
        "Fail": {
            "centers": None,
            "Nearest": 0
        },
        "far": "",
        "Meta": None,
        "Only": False,
        "Tags": None
    },
    "Session": "",
    "conf": {
        "check": "",
        "Reg": ""
    },
    "Token": ""
}

remote_json = [{
    "name": {
        "provide": ""
    },
    "Name": "abc",
    "test": {
        "Service": "redis",
        "Tags": [
            "stage"
        ],
        "Fail": {
            "centers": None,
            "Nearest": 3
        },
        "Only": False,
        "far": "",
        "Meta": None
    },
    "Token": "",
    "Session": "",

    "conf": {
        "Reg": "",
        "check": "name_prefix_match"
    },
}]

Assuming that remote.json is the list of dictionaries & each one of them should be filtered out using default.json:

filtered_remote_json = [dict(item
                             for item in dictionary.items()
                             if item not in default_json.items())
                        for dictionary in remote_json]

will give us

filtered_remote_json == [{"Name": "abc",
                          "test": {"Service": "redis", "Tags": ["stage"],
                                   "Fail": {"centers": None,
                                            "Nearest": 3}, "Only": False,
                                   "far": "", "Meta": None},
                          "conf": {"Reg": "",
                                   "check": "name_prefix_match"}}]

EDIT

if we need to filter sub-dictionaries as well, then next a bit nasty utility function should help

def filter_defaults(json_object, default_json_object):
    result = {}
    for key, value in json_object.items():
        try:
            default_value = default_json_object[key]
        except KeyError:
            # key not in defaults, adding to result
            result[key] = value
            continue

        # we need to process sub-dictionaries as well
        if isinstance(value, dict):
            value = filter_defaults(value, default_value)
            # we are not interested in empty filtered sub-dictionaries
            if not value:
                continue
        # value should differ from default
        elif value == default_value:
            continue

        result[key] = value

    return result

then just write

filtered_remote_json = [filter_defaults(dictionary, default_json)
                        for dictionary in remote_json]

this will give us

filtered_remote_json == [{"Name": "abc",
                          "test": {"Service": "redis", "Tags": ["stage"],
                                   "Fail": {"Nearest": 3}},
                          "conf": {"check": "name_prefix_match"}}]

Upvotes: 2

Related Questions