Home > Blockchain >  Merge Json with same key value pairs
Merge Json with same key value pairs

Time:01-06

I got a resultant json from an API in the following format

[{
        "Uid": "40cc6103-1cf0-4735-b882-d14d32018e58",
        "Id": "9e1a0057-4570-4a6e-8ff5-88b2facbaf4e",
        "Details": {
            "Name": "Kiran"
        }
    }, {
        "Uid": "40cc6103-1cf0-4735-b882-d14d32018e58",
        "Id": "9e1a0057-4570-4a6e-8ff5-88b2facbaf4e",
        "Details": {
            "Age": "24"
        }
    },
    {
        "Uid": "196f5865-e9fe-4847-86ae-97d0bf57b816",
        "Id": "84909ecb-c92e-48a7-bcaa-d478bf3a9220",
        "Details": {
            "Name": "Shreyas"
        }
    }
]

since the Uid and Id are same for multiple entires, can I club them togeather with Details key being the comma seperate key,value pair? Something like mentioned below

[{
    "Uid": "40cc6103-1cf0-4735-b882-d14d32018e58",
    "Id": "9e1a0057-4570-4a6e-8ff5-88b2facbaf4e",
    "Details": {
        "Name": "Kiran",
        "Age": "24"
    }
},
{
    "Uid": "196f5865-e9fe-4847-86ae-97d0bf57b816",
    "Id": "84909ecb-c92e-48a7-bcaa-d478bf3a9220",
    "Details": {
        "Name": "Shreyas"
    }
}]

Please Guide me on this for the approach to be followed. Thanks

CodePudding user response:

What you need is the dictionary function update(). Here's an example:

A = [{
    "Uid": "40cc6103-1cf0-4735-b882-d14d32018e58",
    "Id": "9e1a0057-4570-4a6e-8ff5-88b2facbaf4e",
    "Details": {
        "Name": "Kiran"
    }
}, {
    "Uid": "40cc6103-1cf0-4735-b882-d14d32018e58",
    "Id": "9e1a0057-4570-4a6e-8ff5-88b2facbaf4e",
    "Details": {
        "Age": "24"
    }
},
    {
        "Uid": "196f5865-e9fe-4847-86ae-97d0bf57b816",
        "Id": "84909ecb-c92e-48a7-bcaa-d478bf3a9220",
        "Details": {
            "Name": "Shreyas"
    }
}
]

B = []

def find(uid, id_):
    for i, d in enumerate(B):
        if d['Uid'] == uid and d['Id'] == id_:
            return i
    return -1

for d in A:
    if (i := find(d['Uid'], d['Id'])) < 0:
        B.append(d)
    else:
        B[i]['Details'].update(d['Details'])

print(B)

Prettyfied output:

[
    {
        "Uid": "40cc6103-1cf0-4735-b882-d14d32018e58",
        "Id": "9e1a0057-4570-4a6e-8ff5-88b2facbaf4e",
        "Details": {
            "Name": "Kiran",
            "Age": "24"
        }
    },
    {
        "Uid": "196f5865-e9fe-4847-86ae-97d0bf57b816",
        "Id": "84909ecb-c92e-48a7-bcaa-d478bf3a9220",
        "Details": {
            "Name": "Shreyas"
        }
    }
]

Note:

This could be very inefficient if your API response contains very large numbers of dictionaries. You might need a completely different approach

CodePudding user response:

You should iterate over the list and merge with accumulator with (Uid, Id) as key:

from typing import Dict, List

l = [{
        "Uid": "40cc6103-1cf0-4735-b882-d14d32018e58",
        "Id": "9e1a0057-4570-4a6e-8ff5-88b2facbaf4e",
        "Details": {
            "Name": "Kiran"
        }
    }, {
        "Uid": "40cc6103-1cf0-4735-b882-d14d32018e58",
        "Id": "9e1a0057-4570-4a6e-8ff5-88b2facbaf4e",
        "Details": {
            "Age": "24"
        }
    },
    {
        "Uid": "196f5865-e9fe-4847-86ae-97d0bf57b816",
        "Id": "84909ecb-c92e-48a7-bcaa-d478bf3a9220",
        "Details": {
            "Name": "Shreyas"
        }
    }
]


def mergeItem(it: Dict, acc: Dict) -> Dict:
    uid = it["Uid"]
    id = it["Id"]
    if (uid, id) in acc:
        acc[(uid, id)] = {"Uid": uid, "Id": id, "Details": {**acc[(uid, id)]["Details"], **it["Details"]}}
    else:
        acc[(uid, id)] = {"Uid": uid, "Id": id, "Details": it["Details"]}
    return acc


def mergeList(a:List) -> Dict:
    acc = {}
    for v in a:
        acc = mergeItem(v, acc)
    return acc


print(list(mergeList(l).values()))

# [
#     {
#         'Uid': '40cc6103-1cf0-4735-b882-d14d32018e58',
#         'Id': '9e1a0057-4570-4a6e-8ff5-88b2facbaf4e',
#         'Details': {'Name': 'Kiran', 'Age': '24'}},
#     {
#         'Uid': '196f5865-e9fe-4847-86ae-97d0bf57b816',
#         'Id': '84909ecb-c92e-48a7-bcaa-d478bf3a9220',
#         'Details': {'Name': 'Shreyas'}
#     }
# ]
  •  Tags:  
  • Related