Reputation: 131
I'm using SuperObject to create and manipulate a simple hierarchical structure in JSON.
My goal is to transform a set of objects {"id":..., "name":..., "parent":...} into a hierarchical structure. Example:
I want to transform this
{"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"},
into this
{
"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"
}
]
}
]
}
]
}
(This structure can vary, i.e. there is no fixed model. Which probably means the solution must be recursive).
I think the way to achieve this is:
To do this, I was looking for a way to retrieve the path of an object, like
function findpathinObject(key:string, value:string, object:iSuperObject):string
which would return the "path" of the value found.
In my example, findpathinObject("parent", "0003.1", newObject) would return 'items[2].items[0]'
Is this a good approach? Is there something that resolves my issue without making a new function?
the closest I've seen is this SuperObject - Extract All but I don't know if that can be changed to return the path it is looking in, or the path where it finally found the value...
Thanks
Upvotes: 2
Views: 733
Reputation: 131
Got this from Python: Sorting JSON object(s) into a Hierarchy
In Delphi (it works, here is an extract for guidance):
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;
Upvotes: 1
Reputation: 43023
SuperObject is a JSON access library, not a data processing library. So there is nothing like this available in the box.
You just need to implement the extraction logic in pascal code, using SuperObject for reading the input, and creating the nested output.
Upvotes: 0