Delphi SuperObject - есть ли (рекурсивная) функция поиска, которая сообщает, где можно найти значение?

Я использую 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

который вернул бы "путь" найденного значения.

В моем примере findpathinObject("parent", "0003.1", newObject) вернул бы 'items[2].items[0]'

Это хороший подход? Есть ли что-то, что решает мою проблему без создания новой функции?

самый близкий, который я видел, - это SuperObject - Extract All, но я не знаю, можно ли это изменить, чтобы он возвращал путь, по которому он ищет, или путь, по которому он наконец нашел значение...

Спасибо

1 ответ

Получил это из Python: сортировка объектов JSON в иерархию

В 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, а не библиотека обработки данных. Так что в коробке нет ничего подобного.

Вам просто нужно реализовать логику извлечения в коде Паскаль, используя SuperObject для чтения ввода и создания вложенного вывода.

Другие вопросы по тегам