переформатировать вывод иерархических данных на основе элемента - PullRequest
0 голосов
/ 26 ноября 2018

Учитывая следующий json, который содержит иерархические данные, мне нужно преобразовать следующую плоскую структуру в выходной формат родительского дочернего json:

[{
    "ID": 1042,
    "NameID": "200",
    "Name": "related",
    "path": "1042"
}, {
    "ID": 1561,
    "NameID": "  230",
    "Name": "Patr",
    "FatherID": 1042,
    "path": "1042\/1561"
}, {
    "ID": 1370,
    "NameID": "    230",
    "Name": "Dog",
    "FatherID": 1561,
    "path": "1042\/1561\/1370"
}, {
    "ID": 1560,
    "NameID": "    230.1",
    "Name": "Ort",
    "FatherID": 1561,
    "path": "1042\/1561\/1560"
}, {
    "ID": 213,
    "NameID": "    232",
    "Name": "Jim",
    "FatherID": 1561,
    "path": "1042\/1561\/213"
}]

Как я могу получить вывод, как показано ниже, на основеиерархия путей?:

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

[
  {
    "200": "related",
    "Children": [
      {
        "  230": "Patr",
        "Children": [
          {
            "230.1": "Ort",
            "Children": [
              {
                "NameID": "Name",
                "Children": [
                  {
                    "NameID": "Name",
                    "children": [
                      {
                        "NameID": "Name"
                      },
                      {
                        "NameID": "Name"
                      }
                    ]
                  },
                  {
                    "NameID": "Name",
                    "children": [
                      {
                        "NameID": "Name"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }

1 Ответ

0 голосов
/ 27 ноября 2018

Ключом к следующему решению является преобразование плоского массива в иерархическую структуру.Мы используем setpath, чтобы сделать это следующим образом:

reduce .[] as $element ({};
  setpath($element | .path | split("\/");
          $element | {NameID, Name}))

При вашем вводе это дает следующее:

{
  "1042": {
    "NameID": "200",
    "Name": "related",
    "1561": {
      "NameID": "  230",
      "Name": "Patr",
      "1370": {
        "NameID": "    230",
        "Name": "Dog"
      },
      "1560": {
        "NameID": "    230.1",
        "Name": "Ort"
      },
      "213": {
        "NameID": "    232",
        "Name": "Jim"
      }
    }
  }
}

Теперь это всего лишь вопрос о том, что можно сделать, что можно сделатьиспользуя следующую вспомогательную функцию:

def promote:
  . as $in
  | (if .NameID then {(.NameID): .Name } else {} end) as $base
  | del(.NameID) | del(.Name)
  | if length == 0 then $base
    else $base + {Children: (reduce keys_unsorted[] as $k ([]; . + [$in[$k] | promote] ))}
    end;

С этим определением решение становится:

reduce .[] as $element ({};
  setpath($element | .path | split("\/");
          $element | {NameID, Name}))
| promote
| .Children

Выход

[
  {
    "200": "related",
    "Children": [
      {
        "  230": "Patr",
        "Children": [
          {
            "    230": "Dog"
          },
          {
            "    230.1": "Ort"
          },
          {
            "    232": "Jim"
          }
        ]
      }
    ]
  }
]
...