Search code examples
pythonjsondjangocomparenested-loops

Python - Compare two JSON with different length and without order


I want to compare two json data without order because there are same items with different orders. For example first json:

[{'Id': 113, 'Label': 'Z', 'Input': 'Z', 'Updated': False}, 
 {'Id': 124, 'Label': ' X', 'Input': ' X', 'Updated': False},
 {'Id': 128, 'Label': ' C', 'Input': ' C', 'Updated': False},
 {'Id': 117, 'Label': ' R', 'Input': ' R', 'Updated': False}, 
 {'Id': 118, 'Label': ' T', 'Input': ' T', 'Updated': False}]

Second Json

[{'Id': 128, 'Label': ' C1', 'Input': ' C1', 'Updated': False}, 
 {'Id': 118, 'Label': ' T1', 'Input': ' T1', 'Updated': False}
 {'Id': 113, 'Label': 'Z2', 'Input': 'Z2', 'Updated': False},]

I want to make update different data but same ID json from the second json and delete from the first Json what second json doesnt have. So my loop is below:

for form in selectedUserForm:
    for jsonItem in getJson:
        if form.id == jsonItem['Id'] and form.isUpdated == False:
            form.metaKey = jsonItem['Label']
            form.metaVal = jsonItem['Input']
            form.isUpdated = True
            form.save()
        elif jsonItem['Id'] == 0:
            newMeta = UserMeta(user = selectedUser, metaVal = jsonItem['Input'].title(), metaKey = jsonItem['Label'].title(), isUpdated = True)
            newMeta.full_clean()
            newMeta.save()
        elif form.isUpdated == False:
            form.isDeleted = True
            form.isUpdated = True
            form.save()

However, this algorithm only make with order but my list is posted from fetch data and they are not in same order.


Solution

  • I made the operation with three different loops. First I added 0 id items as new to Query.

    I also made isUpdated=True so it won't count in the other loops because in other loops I will only count isUpdated=False attributed items.

    for jsonItem in getJson:
        if jsonItem['Id'] == 0:
            newMeta = ProductMeta(user=selectedProduct, metaVal=jsonItem['Input'].title(
            ), metaKey=jsonItem['Label'].title(), isUpdated=True)
            newMeta.full_clean()
            newMeta.save()
    

    I call my query that should be updated.

    selectedProductForm = ProductMeta.objects.filter( user=selectedProduct, isDeleted=False, isUpdated=False)

    The overwrite method for update operation.

    for form in selectedProductForm:
        for jsonItem in getJson:
            if form.id == jsonItem['Id'] and form.isUpdated == False:
                if jsonItem['Label'] is not None and jsonItem['Label'][0:1].isalnum() == True:
                    form.metaKey = jsonItem['Label'].title()
                else:
                    form.metaKey = form.metaKey
                if jsonItem['Input'] is not None and jsonItem['Input'][0:1].isalnum() == True:
                    form.metaVal = jsonItem['Input'].title()
                form.isUpdated = True
                form.save()
    

    So, there will be only deletable items left because all of added and overwrited items' isUpdate attribute are False.

    for form in selectedProductForm:
            if form.isUpdated == False:
                form.isDeleted = True
                form.isUpdated = True
                form.save()
    

    After all these operations I make isUpdated=false of all items in order to make update operation again later.

    formRefresh = UserMeta.objects.filter(
        user=selectedProduct).update(isUpdated=False)