Leibnitz
Leibnitz

Reputation: 355

Groovy: Handling nested JSON array objects efficiently

Here is a sample data of JSON that contains nested array of JSON objects.

def content = """[{
  "student" : {
    "studentId" : "ABC001",
    "studentName" : "TOM"
    },
    "details" : {
        "subjects" : {
            "subjectDetails" : [{
                "name" : "MATHS",
                "rating" : 4
            },
            {
                "name" : "SPANISH",
                "rating" : 5
            }
            ]
        }
    }
  },
  {
    "student" : {
    "studentId" : "DEF222",
    "studentName" : "RICK"
    },
    "details" : {
        "subjects" : {
            "subjectDetails" : null
        }
    }
  },
  {
  "student" : {
    "studentId" : "XYZ444",
    "studentName" : "AMY"
    },
    "details" : {
        "subjects" : {
            "subjectDetails" : [{
                "name" : "MATHS",
                "rating" : 6
            },
            {
                "name" : "SPANISH",
                "rating" : 7
            },
            {
                "name" : "PHYSICS",
                "rating" : 9
            }
            ]
        }
    }
  }]"""

Having a JSON content containing multiple nested JSON array objects which has to be separated out as child records. Tried the below code but would like to know if there are efficient ways of doing this incase there are multiple nested arrays. My expected output is below.

def result = new JsonSlurper().parseText(content)

def header = "type," + result.collect{it.student.keySet()}.unique().flatten().join(",")
println header
def childHeader = {try {
    result.details.subjects.subjectDetails.flatten().collect {it.keySet()}.unique().flatten().join(",")
    } catch(Exception e) {'exception'}
}

result.collect {
    students = it.student
    studentsRecord = "Parent," + students.collect { it.value }.join(",")
    println studentsRecord

    subjects = it.details.subjects.subjectDetails

    subjectsRecord = subjects.collect{"Subject-Children," + it.values().join(",")}.join("\n") ?:''
    if (subjectsRecord)
        println subjectsRecord
}

Output:

type,studentId,studentName
Parent,ABC001,TOM
Subject-Children,MATHS,4
Subject-Children,SPANISH,5
Parent,DEF222,RICK
Parent,XYZ444,AMY
Subject-Children,MATHS,6
Subject-Children,SPANISH,7
Subject-Children,PHYSICS,9

Upvotes: 0

Views: 1188

Answers (1)

tim_yates
tim_yates

Reputation: 171084

You can cut that down to:

def result = new JsonSlurper().parseText(content)

println "type,${result.student.head().keySet().join(',')}"
result.each { student ->
    println "Parent,${student.student.values().join(',')}"
    student.details.subjects.subjectDetails.each {
        println "Subject-Children,$it.name,$it.rating"
    }
}

Not sure how you want to measure efficiency though 😉

Do you have an example with "multiple nested arrays"?

Upvotes: 1

Related Questions