0

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
            }]
        }]
}
peak
  • 105,803
  • 17
  • 152
  • 177
Lee
  • 1
  • Hi Lee, Ideally you should be getting data in XML format from backend side for CSV related data further if you want to continue this road is beneficial to convert it to XML then converting it to json is easy. Please check out this solution https://stackoverflow.com/questions/47940264/csv-to-xml-using-javascript – krishank Tripathi Dec 14 '20 at 06:41

1 Answers1

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)
peak
  • 105,803
  • 17
  • 152
  • 177
  • Many thanks for a very quick answer. Very impressive. I will have a look at the data. – Lee Dec 15 '20 at 20:49