Sorting JSON object(s) into a Hierarchy

后端 未结 4 950
感情败类
感情败类 2021-01-06 10:57

I need to sort out a JSON array into a Hierarchy, here my JSON file, it\'s never ordered but follow structure:

{
  \"name\":\"Folder 2\",
  \"id\":\"zRDg\",
         


        
4条回答
  •  走了就别回头了
    2021-01-06 11:53

    What you have here is a graph (probably just a tree) with connections between nodes represented by a parent key. This is known as an adjacency list.

    You want to produce a tree structure with links to other nodes through a children key which is a list of other nodes.

    To convert an adjacency list into a tree, you first need to have a way to retrieve a node by its id, so the first step is to create a dict of every node, keyed by id.

    Then you have to go through the list again and add children to their parents.

    Finally, make a list of nodes without parents (the root nodes).

    Note that you don't need a recursive algorithm at all.

    We can combine some of these steps to avoid going through the list multiple times. Code below:

    def nest_list(L):
        """Modify list of associative dicts into a graph and return roots of graph
    
        Association is via a 'parent' key indicating a corresponding 'id'.
        Items in the list *will be modified*.
        Children will be placed in a list for a 'children' key
        Items without children will have no 'children' key
        'parent' keys will be removed.
    
        Returned list is the full list of items which are not children of
        any other items.
        """
        idx = {}
        children = []
        root = []
        # first pass: index items by id
        # if the item has no parents, put it in the 'root' list
        # otherwise add it to the 'children' list which we will
        # process in a second pass
        for item in L:
            idx[item['id']] = item
            if 'parent' in item:
                children.append(item)
            else:
                root.append(item)
    
        # second pass: find the parents of our children
        for child in children:
            parent = idx[child['parent']]
            del child['parent']
            try:
                # retrieve the list of children for this
                # parent
                childlist = parent['children']
            except KeyError:
                # this item has received no children so far
                # so we need to make a 'children' key and list
                # for it.
                parent['children'] = childlist = []
            # append this child to the parent's list of children
            childlist.append(child)
    
        #all done: return new root list
        return root
    

    Code in action:

    oldlist = [{
      "name":"Folder 2",
      "id":"zRDg",
      "parent":"OY00",
      "type":"folder"
    },
    {
      "name":"Folder 1",
      "id":"OY00",
      "type":"folder"
    },
    {
      "name":"Folder 3",
      "id":"ZDE1",
      "type":"folder"
    },
    {
      "name":"DX00025.jpg",
      "id":"9Xdd",
      "parent":"OY00",
      "type":"jpeg"
    }]
    
    expected = [{
      "name":"Folder 1",
      "id":"OY00",
      "type":"folder",
      "children": [{
        "name":"Folder 2",
        "id":"zRDg",
        "type":"folder"
        },
        {
        "name":"DX00025.jpg",
        "id":"9Xdd",
        "type":"jpeg"
      }]
    },
    {
        "name":"Folder 3",
        "id":"ZDE1",
        "type":"folder"
    }]
    
    
    from pprint import pprint
    newlist = nest_list(oldlist)
    pprint(newlist)
    assert newlist == expected
    

提交回复
热议问题