Home > Blockchain >  Sorting objects and lists in nested JSON
Sorting objects and lists in nested JSON

Time:01-20

I have this JSON:

{
  "data": [
    {
      "Contact": {
        "Name": "Name_of_the_shop"
      },
      "Date": "2022-01-01T11:11:13",
      "DueDate": "2022-01-01T11:11:13",
      "VAT": false,
      "Items": [
        {
          "Code": "3",
          "Description": "Sales",
          "Quantity": 1,
          "TaxAmount": 1,
          "TaxType": "3",
          "UnitAmount": 10
        },
        {
          "AccountCode": "1",
          "Description": "Discount",
          "Quantity": 1,
          "TaxAmount": -0.2,
          "TaxType": "4",
          "UnitAmount": -2
        },
        {
          "AccountCode": "1",
          "Description": "Discount",
          "Quantity": 3,
          "TaxAmount": 1.9,
          "TaxType": "4",
          "UnitAmount": -5
        },
        {
          "Code": "3",
          "Description": "Sales",
          "Quantity": 2,
          "TaxAmount": 1,
          "TaxType": "3",
          "UnitAmount": 8
        }
      ],
      "Payments": [],
      "Reference": "Orders closed 1 Febuary 2022"
    }
  ]
}

And this code to extract all keys and values:

def get_keys_and_values(data, key_list, value_list):
    for key, value in data.items():
        key_list.append(key)
        if not isinstance(value, list) and not isinstance(value, dict):
            value_list.append([key, value])
        if isinstance(value, dict):
            get_keys_and_values(value, key_list, value_list)
        elif isinstance(value, list):
            for val in value:
                get_keys_and_values(val, key_list, value_list)
    return key_list, value_list

I want to sort all dictionaries and lists in this JSON so the output (key_list and value_list) is always the same even if order in the JSON will change. (I dont want to sort key_list, and value_list it has to be done here). I'm relatively new to Python, and I've been stuck here for a while, I would appreciate any help :)

Expected outpu:

key_list:

['AccountCode', 'AccountCode', 'Code', 'Code', 'Contact', 'Date', 'Description', 'Description', 'Description', 'Description', 'DueDate', 'Items', 'Name', 'Payments', 'Quantity', 'Quantity', 'Quantity', 'Quantity', 'Reference', 'TaxAmount', 'TaxAmount', 'TaxAmount', 'TaxAmount', 'TaxType', 'TaxType', 'TaxType', 'TaxType', 'UnitAmount', 'UnitAmount', 'UnitAmount', 'UnitAmount', 'VAT', 'data']

value_list:

[
['Date', '2022-01-01T11:11:13'],
['DueDate', '2022-01-01T11:11:13'],
['Name', 'Name_of_the_shop'],
['Reference', 'Orders closed 1 Febuary 2022']
['VAT', False],
[['AccountCode', '1'], ['Description', 'Discount'], ['TaxAmount', -0.2], ['TaxType', '4'], ['Quantity', 1], ['UnitAmount', -2]],
[['AccountCode', '1'], ['Description', 'Discount'], ['TaxAmount', 1.9], ['TaxType', '4'], ['Quantity', 3], ['UnitAmount', -5]],
[['Code', '3'], ['Description', 'Sales'], ['TaxAmount', 1], ['TaxType', '3'], ['Quantity', 1], ['UnitAmount', 10]],
[['Code', '3'], ['Description', 'Sales'], ['TaxAmount', 1], ['TaxType', '3'], ['Quantity', 2], ['UnitAmount', 8]]
]

CodePudding user response:

Try using the json library with the sort_keys feature.

import json

sorted_json_data = json.dumps(data, sort_keys=True)

CodePudding user response:

@liveware answer seems the saner option.

FWIW here is one way inserting missing keys on each object (so they are always consistent):

new_data = {}
for k, v in json['data'][0].items(): 
    if isinstance(v, list):
        new_list = [] 
        sorted_keys = sorted(set(k for obj in v for k in obj))  # assuming list of dicts
        for obj in v: 
            new_obj = {key: obj.get(key) for key in sorted_keys} 
            new_list.append(new_obj) 
        v = new_list 
    elif isinstance(v, dict): 
        v = {key: obj[key] for key in sorted(obj)} 
    new_data[k] = v 

Output:

{'Contact': {'Code': '3',
  'Description': 'Sales',
  'Quantity': 2,
  'TaxAmount': 1,
  'TaxType': '3',
  'UnitAmount': 8},
 'Date': '2022-01-01T11:11:13',
 'DueDate': '2022-01-01T11:11:13',
 'VAT': False,
 'Items': [{'AccountCode': None,
   'Code': '3',
   'Description': 'Sales',
   'Quantity': 1,
   'TaxAmount': 1,
   'TaxType': '3',
   'UnitAmount': 10},
  {'AccountCode': '1',
   'Code': None,
   'Description': 'Discount',
   'Quantity': 1,
   'TaxAmount': -0.2,
   'TaxType': '4',
   'UnitAmount': -2},
  {'AccountCode': '1',
   'Code': None,
   'Description': 'Discount',
   'Quantity': 3,
   'TaxAmount': 1.9,
   'TaxType': '4',
   'UnitAmount': -5},
  {'AccountCode': None,
   'Code': '3',
   'Description': 'Sales',
   'Quantity': 2,
   'TaxAmount': 1,
   'TaxType': '3',
   'UnitAmount': 8}],
 'Payments': [],
 'Reference': 'Orders closed 1 Febuary 2022'}
  •  Tags:  
  • Related