Fluxy
Fluxy

Reputation: 2978

How to split JSON fields containing '_' into sub-objects?

I have the following JSON object, in which I need to post-process some labels:

{
 'id': '123',
 'type': 'A',
 'fields': 
  {
      'device_safety': 
      {
         'cost': 0.237,
         'total': 22
      },
      'device_unit_replacement': 
      {
         'cost': 0.262,
         'total': 7
      },
      'software_generalinfo': 
      {
         'cost': 3.6,
         'total': 10
      }
  }
}

I need to split the names of labels by _ to get the following hierarchy:

{
 'id': '123',
 'type': 'A',
 'fields': 
  {
      'device': 
      {
         'safety': 
         {
             'cost': 0.237,
             'total': 22
         },
         'unit':
         {
             'replacement':
             {
                  'cost': 0.262,
                  'total': 7
             }  
         }
      },
      'software': 
      {
         'generalinfo':
         {
            'cost': 3.6,
            'total': 10
         }
      }
  }
}

This is my current version, but I got stuck and not sure how to deal with the hierarchy of fields:

import json

json_object = json.load(raw_json)

newjson = {}
for x, y in json_object['fields'].items():
    hierarchy = y.split("_")
    if len(hierarchy) > 1:
         for k in hierarchy:
              newjson[k] = ????

newjson = json.dumps(newjson, indent = 4)

Upvotes: 2

Views: 107

Answers (1)

user2390182
user2390182

Reputation: 73480

Here is recursive function that will process a dict and split the keys:

def splitkeys(dct):
    if not isinstance(dct, dict):
        return dct
    new_dct = {}
    for k, v in dct.items():
        bits = k.split('_')
        d = new_dct
        for bit in bits[:-1]:
            d = d.setdefault(bit, {})
        d[bits[-1]] = splitkeys(v)
    return new_dct


>>> splitkeys(json_object)
{'fields': {'device': {'safety': {'cost': 0.237, 'total': 22},
                       'unit': {'replacement': {'cost': 0.262, 'total': 7}}},
            'software': {'generalinfo': {'cost': 3.6, 'total': 10}}},
 'id': '123',
 'type': 'A'}

Upvotes: 2

Related Questions