2

我正在使用 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 但我不知道是否可以更改它以返回它正在查找的路径,或者它最终找到值的路径......

谢谢

4

2 回答 2

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;
于 2019-02-25T22:12:00.293 回答
0

SuperObject 是 JSON 访问库,而不是数据处理库。所以盒子里没有这样的东西。

您只需要在 pascal 代码中实现提取逻辑,使用 SuperObject 读取输入并创建嵌套输出。

于 2018-11-14T17:32:17.943 回答