问题
This is a continue of another post: JQ, convert CSV (parent child format) to JSON
Hi, sorry to ask again. I tried to get the following format, without success. Really appreciate for some advice. I attach a picture to show how it looks like in a hierarchy view a picture to show in a hierarchy way, maybe it is easier. Hope it is possible ?
*** CSV file *****
id,parent_id,size Subject,Null,1 analytics,Subject,1 cluster,analytics,1 AgglomerativeCluster,cluster,1 MergeEdge,cluster,2 animate,Subject,1 Easing,animate,3 interpolate,animate,1 ArrayInterpolator,interpolate,4 RectangleInterpolator,interpolate,5 Tween,animate,6
Here is the JSON file which I tried to achieve. If it is a parent (has a child under), only show ID. If it is a child, then show ID and Size.
**** JSON file ****
{
"ID": "Subject",
"children": [{
"ID": "analytics",
"children": [{
"ID": "cluster",
"children": [{
"ID": "Aggl,ome,rativeCluster",
"size": 1
}, {
"ID": "MergeEdge",
"size": 2
}]
}]
}, {
"ID": "animate",
"children": [{
"ID": "Easing",
"size": 3
}, {
"ID": "interpolate",
"children": [{
"ID": "ArrayInterpolator",
"size": 4
}, {
"ID": "RectangleInterpolator",
"size": 5
}]
}, {
"ID": "Tween",
"size": 6
}]
}]
}
回答1:
To fill in the details about children recursively can most easily be
accomplished using a recursive function -- here closure/2, which is written so as to be quite efficient.
def obj($headers):
. as $in
| reduce range(0; $headers|length) as $i ({};
.[$headers[$i]] = $in[$i]);
# input: either the id of an individual or
# an object representing an individual;
# output: the same individual but with .children and recursively
# their children as an array of objects
def closure($dictionary; $children):
def c:
if type == "string" then $dictionary[.] | c
elif type=="object"
then if has("children")
then if (.children|length)>0 then .children = map(c) else . end
elif $children[.id] then .children = ($children[.id] | map(c))
else . end
else . end;
c;
split(",") as $headers
| [ inputs
| split(",")
| map_values(if . == "Null" then null else . end)
| obj($headers) ]
| INDEX(.[]; .id) as $ids # a dictionary mapping id => object
| (reduce .[] as $row ({};
if $row.parent_id
then .[$row.parent_id] += [$row.id]
else . end ) ) as $children # string => [ string ]
| map(closure($ids; $children) )
# tidy up:
| walk(if type=="object"
then if .children and (.children|length) > 0
then del(.size)
else . end
| del(.parent_id)
else . end)
来源:https://stackoverflow.com/questions/65278602/jq-convert-csv-parent-child-format-to-json-another-questions