基于元素重新格式化分层数据的输出
reformat output of hierarchical data, based on an element
鉴于以下 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"
}
]
}
]
}
]
}
]
}
]
}
下面的解决方案的关键是将平面数组转换为层次结构。我们使用 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"
}
]
}
]
}
]
鉴于以下 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"
}
]
}
]
}
]
}
]
}
]
}
下面的解决方案的关键是将平面数组转换为层次结构。我们使用 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"
}
]
}
]
}
]