json - 如何解决jsonb中的递归嵌套树?
问题描述
所以我有一棵像这样的扁平树:
[{
aid: "id3"
atype: ""
data: ["id1", "id2"]
},
{
aid: "id1"
atype: ""
data: ["id3", "id2"]
},
{
aid: "id2"
atype: ""
bdata: {aid: "id4", atype: "nested", data: ["id1", "id3"]}
data: []
}]
我想收集那棵树并使用递归循环将 id 解析为数据,就像这样(比如我们从 开始"id3"
):
{
aid: "id3"
payload: "1"
data: [
"id1":{
aid: "id1"
atype: ""
data: ["id3":Null, "id2":Null]
},
"id2":{
aid: "id2"
atype: ""
bdata: {aid: "id4", atype: "nested", data: ["id1":Null, "id3":Null]}
data: []
}]
}
这样我们就可以进行广度优先搜索并"value": "object with that field"
在第一次进入时将某些字段解析为"value": Null
那么如何在 Postgres JSONb\ JSON中将这样的列表实现到树中呢?
我知道可以使用 PL/Python 之类的东西来做到这一点,但我没有看到一个 PL/Python 函数示例可以做这样的事情,比如不将所有 JSON 记录放入 ram 中......
{'id1': {'aid': 'id1', 'atype': '', 'data': ['id3', 'id2']},
'id2': {'aid': 'id2',
'atype': '',
'bdata': {'aid': 'id4', 'atype': 'nested', 'data': ['id1', 'id3']},
'data': []},
'id3': {'aid': 'id3', 'atype': '', 'data': ['id1', 'id2']}}
对我来说不是真的有用 - 所以我需要一棵真正的树。
解决方案
你的方法有问题。
让我们考虑跟随json。
{
"aid": "id3",
"atype": "",
"data": ["id1", "id2"]
},
{
"aid": "id4",
"atype": "",
"data": ["id1", "id2"]
}
在这里,id1和id2数据需要为id4再次复制,会产生大量重复数据。
取而代之的是,将您的数据转换为字典。您只需调用“id1”、“id2”等id 即可访问数据。
data_map = {}
for data in data_array:
data_map.__setitem__(data['aid'], data)
以下将是示例输出。
{
"id3": {
"aid": "id3",
"atype": "",
"data": [
"id1", "id2"
]
}
这样您就可以直接访问 id 并且在结构中没有重复项。
完整的示例代码
import json
json_data = '''
[
{
"aid": "id3",
"atype": "",
"data": ["id1", "id2"]
},
{
"aid": "id1",
"atype": "",
"data": ["id3", "id2"]
},
{
"aid": "id2",
"atype": "",
"bdata": {"aid": "id4", "atype": "nested", "data": ["id1", "id3"]},
"data": []
}
]
'''
data_array = json.loads(json_data)
data_map = {}
for data in data_array:
data_map.__setitem__(data['aid'], data)
print(data_map)
推荐阅读
- android - Jetpack Compose Text 超链接部分文本
- django - OuterRef 如何在 django 中工作?
- ruby - times 方法返回 nil 和 hash
- python - 从堆叠的 pandas 数据框中获取 JSON
- swiftui - SwiftUI:从工具栏中选择内部 NavigationList 项
- c# - 无法移动 sqlite 数据库,即使在关闭连接后也是如此
- python - DJANGO_SETTINGS_MODULE Visual Studio 代码终端错误
- javascript - 为后续客户端请求设置授权标头
- javascript - 1个单行mysql上的多个dropzone上传
- node.js - 通过将cookie传递给nodejs中的请求来设置cookie