簡體   English   中英

遞歸構建分層JSON樹?

[英]Recursively build hierarchical JSON tree?

我有一個父子連接數據庫。 數據看起來如下所示,但可以以您想要的任何方式呈現(字典,列表,JSON等)。

links=(("Tom","Dick"),("Dick","Harry"),("Tom","Larry"),("Bob","Leroy"),("Bob","Earl"))

我需要的輸出是一個分層的JSON樹,它將用d3渲染。 數據中有離散的子樹,我將附加到根節點。 所以我需要遞歸地遍歷鏈接,並構建樹結構。 我能得到的最遠的是遍歷所有人並追加他們的孩子,但我無法想出更高階的鏈接(例如如何將帶孩子的人附加到其他人的孩子身上)。 這與此處的另一個問題類似,但我無法事先知道根節點,因此我無法實現已接受的解決方案。

我將從我的示例數據中獲取以下樹結構。

{
"name":"Root",
"children":[
    {
     "name":"Tom",
     "children":[
         {
         "name":"Dick",
         "children":[
             {"name":"Harry"}
         ]
         },
         {
          "name":"Larry"}
     ]
    },
    {
    "name":"Bob",
    "children":[
        {
        "name":"Leroy"
        },
        {
        "name":"Earl"
        }
    ]
    }
]
}

這個結構在我的d3布局中呈現如下。 渲染圖像

要識別根音符,您可以解壓縮links並查找非兒童的父母:

parents, children = zip(*links)
root_nodes = {x for x in parents if x not in children}

然后你可以應用遞歸方法:

import json

links = [("Tom","Dick"),("Dick","Harry"),("Tom","Larry"),("Bob","Leroy"),("Bob","Earl")]
parents, children = zip(*links)
root_nodes = {x for x in parents if x not in children}
for node in root_nodes:
    links.append(('Root', node))

def get_nodes(node):
    d = {}
    d['name'] = node
    children = get_children(node)
    if children:
        d['children'] = [get_nodes(child) for child in children]
    return d

def get_children(node):
    return [x[1] for x in links if x[0] == node]

tree = get_nodes('Root')
print json.dumps(tree, indent=4)

我使用了一個集合來獲取根節點,但如果順序很重要,您可以使用列表並刪除重復項

嘗試以下代碼:

import json

links = (("Tom","Dick"),("Dick","Harry"),("Tom","Larry"),("Tom","Hurbert"),("Tom","Neil"),("Bob","Leroy"),("Bob","Earl"),("Tom","Reginald"))

name_to_node = {}
root = {'name': 'Root', 'children': []}
for parent, child in links:
    parent_node = name_to_node.get(parent)
    if not parent_node:
        name_to_node[parent] = parent_node = {'name': parent}
        root['children'].append(parent_node)
    name_to_node[child] = child_node = {'name': child}
    parent_node.setdefault('children', []).append(child_node)

print json.dumps(root, indent=4)

如果您想將數據格式化為HTML / JS本身的層次結構,請查看:

從flat json生成(多級)flare.json數據格式

如果您擁有大量數據,Web轉換將更快,因為它使用reduce功能而Python缺少函數式編程。

順便說一句:我也在研究相同的主題,即在d3.js中生成可折疊的樹結構。 如果您想繼續工作,我的電子郵件是:erprateek.vit@gmail.com。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM