pythonjsoncomparediffunordered

Multilevel JSON diff in python


Please link me to answer if this has already been answered, my problem is i want to get diff of multilevel json which is unordered.

x=json.loads('''[{"y":2,"x":1},{"x":3,"y":4}]''')
y=json.loads('''[{"x":1,"y":2},{"x":3,"y":4}]''')
z=json.loads('''[{"x":3,"y":4},{"x":1,"y":2}]''')

import json_tools as jt
import json_delta as jd


print jt.diff(y,z)
print jd.diff(y,z)
print y==z
print x==y

output is

[{'prev': 2, 'value': 4, 'replace': u'/0/y'}, {'prev': 1, 'value': 3, 'replace': u'/0/x'}, {'prev': 4, 'value': 2, 'replace': u'/1/y'}, {'prev': 3, 'value': 1, 'replace': u'/1/x'}]
[[[2], {u'y': 2, u'x': 1}], [[0]]]
False
True

my question is how can i get y and z to be equal or if there are actual differences depending on non-order of the JSON.

kind of unordered List of dictionaries but i am looking for something which is level-proof that is list/dict of dictionaries of list/dictionaries ...


Solution

  • solved it partially with following function

    def diff(prev,lat):
        p=prev
        l=lat
    
    
        prevDiff = []
        latDiff = []
    
        for d1 in p[:]:
            flag = False
            for d2 in l:
                if len(set(d1.items()) ^ set(d2.items())) == 0:
                    p.remove(d1)
                    l.remove(d2)
                    flag = True
                    break
            if not flag:
                prevDiff.append(d1)
                p.remove(d1)
    
        prevDiff = prevDiff + p
        latDiff = latDiff + l
    
        resJSONdata=[]
        if len(prevDiff) != 0:
            resJSONdata.append({'prevCount':len(prevDiff)})
            resJSONdata.append({'prev':prevDiff})
        if len(latDiff) != 0:
            resJSONdata.append({'latestCount':len(latDiff)})
            resJSONdata.append({'latest':latDiff})
    
    #     return json.dumps(resJSONdata,indent = 4,sort_keys=True)
        return resJSONdata
    

    it's not doing it recursively into level into levels but for my purpose this solved the issue