-1

I have the following JSON data:

{
    "data": {
        "databis": {
            "dataexit": {
                "databis2": {
                    "1250": { }
                }
            },
            "datanode": {
                "20544": { }
            }
        }
    }
}

I want to use it to generate a D3 sunburst diagram, but that requires a different data format:

{
    "name": "data",
    "children": [ 
        {
            "name": "databis",
            "children": [
                {
                    "name": "dataexit",
                    "children": [
                        {
                            "name": "databis2",
                            "size": "1250"
                        }
                    ]
                },
                {
                    "name": "datanode",
                    "size": "20544"
                }
            ]
        }
    ]
}

How can I do this with Python? I think I need to use a recursive function, but I don't know where to start.

ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110
Amar AttilaZz
  • 242
  • 3
  • 5
  • 13

1 Answers1

1

You could use recursive solution with function that takes name and dictionary as parameter. For every item in given dict it calls itself again to generate list of children which look like this: {'name': 'name here', 'children': []}.

Then it will check for special case where there's only one child which has key children with value of empty list. In that case dict which has given parameter as a name and child name as size is returned. In all other cases function returns dict with name and children.

import json

data = {
    "data": {
        "databis": {
            "dataexit": {
                "databis2": {
                    "1250": { }
                }
            },
            "datanode": {
                "20544": { }
            }
        }
    }
}

def helper(name, d):
    # Collect all children
    children = [helper(*x) for x in d.items()]

    # Return dict containing size in case only child looks like this:
    # {'name': '1250', 'children': []}
    # Note that get is used to so that cases where child already has size
    # instead of children work correctly
    if len(children) == 1 and children[0].get('children') == []:
        return {'name': name, 'size': children[0]['name']}

    # Normal case where returned dict has children
    return {'name': name, 'children': [helper(*x) for x in d.items()]}

def transform(d):
    return helper(*next(iter(d.items())))

print(json.dumps(transform(data), indent=4))

Output:

{
    "name": "data",
    "children": [
        {
            "name": "databis",
            "children": [
                {
                    "name": "dataexit",
                    "children": [
                        {
                            "name": "databis2",
                            "size": "1250"
                        }
                    ]
                },
                {
                    "name": "datanode",
                    "size": "20544"
                }
            ]
        }
    ]
}
niemmi
  • 17,113
  • 7
  • 35
  • 42