3

Scenario : Given an input as below sampleArray , I will like to group all the students having a specific teacher.

In DataWeave we have a method groupBy that allows us to group arrays specifying a string key. But here since item.studentsMarks.subjectTeacher returns an array I am getting an error specified below.

Can anyone please help. Thanks in Advance.

Attached below is expected output.

Sample Input:

var sampleArray = [
    {
        "studentName" : "ABC",  
        "studentsMarks" : [
            {
                "subject" : "maths",
                "marks" : "50",
                "subjectTeacher" : "teacher_1"
            },
            {
                "subject" : "science",
                "marks" : "30",
                "subjectTeacher" : "teacher_3"
            }
        ]
    },
    {
        "studentName" : "XYZ",  
        "studentsMarks" : [
            {
                "subject" : "maths",
                "marks" : "90",
                "subjectTeacher" : "teacher_1"

            },
            {
                "subject" : "arts",
                "marks" : "50", 
                "subjectTeacher" : "teacher_2"
            }
        ]
    }
]


Code tried:

payload groupBy ((item, index) -> item.studentsMarks.subjectTeacher)

Error:

Cannot coerce Array to String

Expected Output :

[
    
    "teacher_1" : [{
            "studentName" : "ABC",  
            "studentsMarks" : [
                {
                    "subject" : "maths",
                    "marks" : "50",
                    "subjectTeacher" : "teacher_1"
                },
                {
                    "subject" : "science",
                    "marks" : "30",
                    "subjectTeacher" : "teacher_3"
                }
            ]
        },    
        {
                "studentName" : "XYZ",  
                "studentsMarks" : [
                    {
                        "subject" : "maths",
                        "marks" : "90",
                        "subjectTeacher" : "teacher_1"
        
                    },
                    {
                        "subject" : "arts",
                        "marks" : "50", 
                        "subjectTeacher" : "teacher_2"
                    }
                ]
           }
    ],
    "teacher_2" : [
        
                {
                "studentName" : "XYZ",  
                "studentsMarks" : [
                    {
                        "subject" : "maths",
                        "marks" : "90",
                        "subjectTeacher" : "teacher_1"
        
                    },
                    {
                        "subject" : "arts",
                        "marks" : "50", 
                        "subjectTeacher" : "teacher_2"
                    }
                ]
           }
    ],
    "teacher_3" : [
        
{
            "studentName" : "ABC",  
            "studentsMarks" : [
                {
                    "subject" : "maths",
                    "marks" : "50",
                    "subjectTeacher" : "teacher_1"
                },
                {
                    "subject" : "science",
                    "marks" : "30",
                    "subjectTeacher" : "teacher_3"
                }
            ]
        }
    ]
        
]

Bibek Kr. Bazaz
  • 505
  • 10
  • 34
  • What is the output like? BTW the issue is with this experession `item.studentsMarks.subjectTeacher` because `item.studentsMarks` is an array--as such the next `.subjectTeacher` is a selector very similar to `.*subjectTeacher`, which returns an array, hence why you get the error you get. – George Dec 08 '20 at 15:44
  • @George Hi, I have attached the expected output. I understood the issue but am looking for a way to implement the solution using groupBy. please let me know if you can find a suitable approach. Many thanks – Bibek Kr. Bazaz Dec 08 '20 at 15:54

1 Answers1

4

Here's a pretty quick way to get it done. It entails more than just a groupBy though:

%dw 2.0
output application/json

var sampleArray = [
    {
        "studentName" : "ABC",  
        "studentsMarks" : [
            {
                "subject" : "maths",
                "marks" : "50",
                "subjectTeacher" : "teacher_1"
            },
            {
                "subject" : "science",
                "marks" : "30",
                "subjectTeacher" : "teacher_3"
            }
        ]
    },
    {
        "studentName" : "XYZ",  
        "studentsMarks" : [
            {
                "subject" : "maths",
                "marks" : "90",
                "subjectTeacher" : "teacher_1"

            },
            {
                "subject" : "arts",
                "marks" : "50", 
                "subjectTeacher" : "teacher_2"
            }
        ]
    }
]
---
// Get list of all teachers
sampleArray..*subjectTeacher
// Change the collection to a set 
distinctBy $ 
// Iterate over every single teacher and create an object where
// the field is the teacher while the value is a collection
// containing all students where they attend a class for the teacher.
map {
    ($): (sampleArray dw::core::Arrays::partition (e) -> e..*subjectTeacher contains $).success
}
George
  • 2,758
  • 12
  • 16
  • can you please explain your approach. – Bibek Kr. Bazaz Dec 08 '20 at 17:30
  • 2
    Annotated the code with comments. If the algorithm is the problem then the comments will help. If the problem is lack of knowledge of any of the functions I use please let me know and I 'll add links to documentation. – George Dec 08 '20 at 18:07
  • 1
    The comments will help any visitor quickly understand the solution and use it for their use case. I went through the methods and understood it. Appreciate the effort. – Bibek Kr. Bazaz Dec 08 '20 at 18:18