I am looking for a flexible way to define JSON transformations and started trying out JSONata. For my simple usecase I need to first group elements in a list by a string value (which I can do) and then group the result with another list.
My question is is this possible and if so how? I feel that some of the higher-order functions might help but I haven't worked out how to access an object in the "outer-scope" from the inner one.
This is my obfuscated data:
{
"grades": [
{
"student_name": "John Smith",
"grade": "B"
},
{
"student_name": "Jane Doe",
"grade": "A"
}
],
"grades_by_subject": [
{
"student_name": "John Smith",
"subject": "English",
"grade": "A"
},
{
"student_name": "Jane Doe",
"subject": "Math",
"grade": "A+"
},
{
"student_name": "John Smith",
"subject": "Math",
"grade": "A"
},
{
"student_name": "Jane Doe",
"subject": "English",
"grade": "C-"
}
]
}
This is the JSONata transformation I have so far:
{
"students": grades_by_subject{`student_name`: {
"grades_by_subject":
$.{
"subject":
subject,
"grade": grade
}
}
}
}
Which gives this result:
{
"students": {
"John Smith": {
"grades_by_subject": [
{
"subject": "English",
"grade": "A"
},
{
"subject": "Math",
"grade": "A"
}
]
},
"Jane Doe": {
"grades_by_subject": [
{
"subject": "Math",
"grade": "A+"
},
{
"subject": "English",
"grade": "C-"
}
]
}
}
}
But the result I actually want is:
{
"students": {
"John Smith": {
"overall_grade": {
"student_name": "John Smith",
"grade": "B"
},
"grades_by_subject": [
{
"subject": "English",
"grade": "A"
},
{
"subject": "Math",
"grade": "A"
}
]
},
"Jane Doe": {
"overall_grade": {
"student_name": "Jane Doe",
"grade": "A"
},
"grades_by_subject": [
{
"subject": "Math",
"grade": "A+"
},
{
"subject": "English",
"grade": "C-"
}
]
}
}
Here's one way to do it:
{
"students": grades_by_subject{
student_name: {
"overall_grade": (
$name := student_name;
$$.grades[student_name = $name[0]]
),
"grades_by_subject": $.{
"subject": subject,
"grade": grade
}
}
}
}
What I did is I took the student_name
from the grouping context and then used it to filter the grades
array from the root context.
Check it out on the Stedi playground: https://stedi.link/CEzbQu4