Delphi SuperObject - 是否有一个(递归)搜索函数可以告诉在哪里可以找到一个值?
Delphi SuperObject - is there a (recursive) search function that tells where a value can be found?
我正在使用 SuperObject 在 JSON 中创建和操作一个简单的层次结构。
我的目标是将一组对象 {"id":..., "name":..., "parent":...} 转换为层次结构。示例:
我要改造这个
{"id": "0001","name": "item0001", "parent":""},
{"id": "0002","name": "item0002", "parent":""},
{"id": "0003","name": "item0003", "parent":""},
{"id": "0003.1","name": "item0003.1", "parent":"0003"},
{"id": "0003.1.1","name": "item0003.1.1", "parent":"0003.1"},
进入这个
{
"items": [
{
"id": "0001",
"name": "item0001"
},
{
"id": "0002",
"name": "item0002"
},
{
"id": "0003",
"name": "item0003",
"items": [
{
"id": "0003.1",
"name": "item0003.1",
"items": [
{
"id": "0003.1.1",
"name": "item0003.1.1"
}
]
}
]
}
]
}
(这个结构可以变化,即没有固定的模型。这可能意味着解决方案必须是递归的)。
我认为实现的方法是:
- 对于每个要添加的对象,
- 如果没有父级,将其添加到输出 json,在顶部;
- 如果有父级,则查找父级在输出中的位置 json。
- 将对象添加到父项下的输出 json。
为此,我正在寻找一种方法来检索对象的路径,例如
function findpathinObject(key:string, value:string, object:iSuperObject):string
这将 return 找到的值的 "path"。
在我的示例中,findpathinObject("parent", "0003.1", newObject) 会 return 'items[2].items[0]'
这是一个好方法吗?有什么东西可以在不创建新功能的情况下解决我的问题吗?
我见过最接近的是这个
SuperObject - Extract All
但我不知道是否可以将其更改为 return 它正在查找的路径,或者它最终找到值的路径...
谢谢
SuperObject 是一个 JSON 访问库,而不是数据处理库。所以盒子里没有这样的东西。
您只需在 Pascal 代码中实现提取逻辑,使用 SuperObject 读取输入并创建嵌套输出。
从 Python 得到这个:
Sorting JSON object(s) into a Hierarchy
在 Delphi 中(有效,这里是指导的摘录):
function ProcessObject(const aAsObject: iSuperObject): iSuperObject;
var
var KeyedObject: iSuperObject
item: iSuperObject;
ArrayItem: iSuperObject;
parent, tgt: iSuperObject;
begin
KeyedObject := SO('{}');
for ArrayItem in aAsObject do
begin
KeyedObject[ArrayItem['id'].AsString] := ArrayItem;
end;
// iterate through each item in the `myJson` list.
for item in aAsObject do
begin
// does the item have a parent?
if assigned(item['parent.id']) then
begin
// get the parent item
if (assigned(item['parent']) and assigned(item['parent.id'])) then
begin
if (assigned(KeyedObject[item['parent'].AsString])) then
parent := KeyedObject[item['parent.id'].AsString];
// if the parent item doesn't have a "children" member,
// we must create one.
if not(assigned(parent['children'])) then
parent['children'] := SO('{[]}');
// add the item to its parent's "children" list.
parent['children[]'] := item;
end;
end;
end;
tgt := SO('{}');
for item in aAsObject do
if not assigned(item['parent']) then
tgt[] := item;
result := tgt;
end;
我正在使用 SuperObject 在 JSON 中创建和操作一个简单的层次结构。
我的目标是将一组对象 {"id":..., "name":..., "parent":...} 转换为层次结构。示例:
我要改造这个
{"id": "0001","name": "item0001", "parent":""},
{"id": "0002","name": "item0002", "parent":""},
{"id": "0003","name": "item0003", "parent":""},
{"id": "0003.1","name": "item0003.1", "parent":"0003"},
{"id": "0003.1.1","name": "item0003.1.1", "parent":"0003.1"},
进入这个
{
"items": [
{
"id": "0001",
"name": "item0001"
},
{
"id": "0002",
"name": "item0002"
},
{
"id": "0003",
"name": "item0003",
"items": [
{
"id": "0003.1",
"name": "item0003.1",
"items": [
{
"id": "0003.1.1",
"name": "item0003.1.1"
}
]
}
]
}
]
}
(这个结构可以变化,即没有固定的模型。这可能意味着解决方案必须是递归的)。
我认为实现的方法是:
- 对于每个要添加的对象,
- 如果没有父级,将其添加到输出 json,在顶部;
- 如果有父级,则查找父级在输出中的位置 json。
- 将对象添加到父项下的输出 json。
为此,我正在寻找一种方法来检索对象的路径,例如
function findpathinObject(key:string, value:string, object:iSuperObject):string
这将 return 找到的值的 "path"。
在我的示例中,findpathinObject("parent", "0003.1", newObject) 会 return 'items[2].items[0]'
这是一个好方法吗?有什么东西可以在不创建新功能的情况下解决我的问题吗?
我见过最接近的是这个 SuperObject - Extract All 但我不知道是否可以将其更改为 return 它正在查找的路径,或者它最终找到值的路径...
谢谢
SuperObject 是一个 JSON 访问库,而不是数据处理库。所以盒子里没有这样的东西。
您只需在 Pascal 代码中实现提取逻辑,使用 SuperObject 读取输入并创建嵌套输出。
从 Python 得到这个: Sorting JSON object(s) into a Hierarchy
在 Delphi 中(有效,这里是指导的摘录):
function ProcessObject(const aAsObject: iSuperObject): iSuperObject;
var
var KeyedObject: iSuperObject
item: iSuperObject;
ArrayItem: iSuperObject;
parent, tgt: iSuperObject;
begin
KeyedObject := SO('{}');
for ArrayItem in aAsObject do
begin
KeyedObject[ArrayItem['id'].AsString] := ArrayItem;
end;
// iterate through each item in the `myJson` list.
for item in aAsObject do
begin
// does the item have a parent?
if assigned(item['parent.id']) then
begin
// get the parent item
if (assigned(item['parent']) and assigned(item['parent.id'])) then
begin
if (assigned(KeyedObject[item['parent'].AsString])) then
parent := KeyedObject[item['parent.id'].AsString];
// if the parent item doesn't have a "children" member,
// we must create one.
if not(assigned(parent['children'])) then
parent['children'] := SO('{[]}');
// add the item to its parent's "children" list.
parent['children[]'] := item;
end;
end;
end;
tgt := SO('{}');
for item in aAsObject do
if not assigned(item['parent']) then
tgt[] := item;
result := tgt;
end;