skip to Main Content

I have data like this which represents hierarchical tree structure:

[
    {
        "level":0,
        "name":"python"
    },
    {
        "level":1,
        "name":"food"
    },
    {
        "level":2,
        "name":"banana"
    },
    {
        "level":3,
        "name":"protein"
    },
    {
        "level":2,
        "name":"apple"
    },
    {
        "level":1,
        "name":"fuel"
    }
]

I want to transform it into:

[
    {
        "level":0,
        "name":"python",
        "children":[
            {
                "level":1,
                "name":"food",
                "children":[
                    {
                        "level":2,
                        "name":"banana",
                        "children":[
                            {
                                "level":3,
                                "name":"protein",
                                "children":[
                                    
                                ]
                            }
                        ]
                    },
                    {
                        "level":2,
                        "name":"apple",
                        "children":[
                            
                        ]
                    }
                ]
            },
            {
                "level":1,
                "name":"fuel",
                "children":[
                    
                ]
            }
        ]
    }
]

I am using python and would prefer the solution in python with or without using external libraries, (even using pandas). I would love to see the solutions, thank you in advance 🙂

2

Answers


  1. Here is one way:

    def create_tree(nodes):
        # add parent information to each node
        for i, node in enumerate(nodes):
            if node['level'] == 0:
                node['parent'] = None
            else:
                j = i - 1
                while j >= 0:
                    if nodes[j]['level'] < node['level']:
                        node['parent'] = nodes[j]['name']
                        break
                    j -= 1
        
        
        node_dict = {}
        for node in nodes:
            node_dict[node['name']] = node
        
        for node in nodes:
            parent_name = node.get('parent')
            if parent_name is not None:
                parent = node_dict[parent_name]
                if 'children' not in parent:
                    parent['children'] = []
                parent['children'].append(node)
        
        for node in nodes:
            if node.get('parent') is None:
                return node
        return None
    
    nodes = [
        {"level":0,"name":"python"},
        {"level":1,"name":"food"},
        {"level":2,"name":"banana"},
        {"level":3,"name":"protein"},
        {"level":2,"name":"apple"},
        {"level":1,"name":"fuel"}
    ]
    
    tree = create_tree(nodes)
    
    print(tree)
    
    
    

    which gives what you wanted

    {'level': 0, 'name': 'python', 'parent': None, 'children': [{'level': 1, 'name': 'food', 'parent': 'python', 'children': [{'level': 2, 'name': 'banana', 'parent': 'food', 'children': [{'level': 3, 'name': 'protein', 'parent': 'banana'}]}, {'level': 2, 'name': 'apple', 'parent': 'food'}]}, {'level': 1, 'name': 'fuel', 'parent': 'python'}]}
    
    Login or Signup to reply.
  2. I suppose the order of the dictionaries in your list matters, since otherwise I wouldn’t know under which parent the children are supposed to be listed. I would suggest to write a recursive function to get the last element at level n and append the children there:

    import json
    
    input_list = [
        {
            "level":0,
            "name":"python"
        },
        {
            "level":1,
            "name":"food"
        },
        {
            "level":2,
            "name":"banana"
        },
        {
            "level":3,
            "name":"protein"
        },
        {
            "level":2,
            "name":"apple"
        },
        {
            "level":1,
            "name":"fuel"
        }
    ]
    
    def get_last_elt_at_lvl(rec, lvl):
        if lvl == 0:
            return rec[-1]
        else:
            for i in range(len(rec)-1,-1,-1):
                if rec[i]['children']:
                    r = get_last_elt_at_lvl(rec[-1]['children'], lvl-1)
                    if r:
                        return r
        return None
    
    output_list = []
    for d in input_list:
        if d["level"] == 0:
            output_list.append(d)
        else:
            last_elt = get_last_elt_at_lvl(output_list, d["level"]-1)
            children = last_elt.setdefault('children', [])
            children.append(d)
    
    print(json.dumps(output_list, indent=4))
    

    Output:

    [
        {
            "level": 0,
            "name": "python",
            "children": [
                {
                    "level": 1,
                    "name": "food",
                    "children": [
                        {
                            "level": 2,
                            "name": "banana",
                            "children": [
                                {
                                    "level": 3,
                                    "name": "protein"
                                }
                            ]
                        },
                        {
                            "level": 2,
                            "name": "apple"
                        }
                    ]
                },
                {
                    "level": 1,
                    "name": "fuel"
                }
            ]
        }
    ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search