2

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:

  • for each object to add,
    • if there is no parent, add it to the output json, at the top;
    • if there is a parent, find where the parent is in the output json.
    • add the object to the output json under the parent.

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

  • curious about why the question was downvoted after the very detailed description of the problem and the research I did trying to get to a solution. I can't improve the question if there is no explanation for the downvote. – costateixeira Nov 14 '18 at 14:25

2 Answers2

1

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;
0

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.

Arnaud Bouchez
  • 42,305
  • 3
  • 71
  • 159
  • Thanks. I noticed some built-in functions and I was wondering if anyone had seen some function (or implemented something) that would iterate through all the elements and keep track of the path. The problem description was also to get advice on whether I was looking at this the right way. I will try to implement it. – costateixeira Nov 14 '18 at 18:40