Message Boards Message Boards

Examples of Query[]

GROUPS:

I routinely work with nested Associations that might be efficiently queried and manipulated with the Query[] command, but I have trouble making the command do what I want. A trivial example:

The following dataset describes a couple of grades at a hypothetical secondary school.

sampleStructure = {<|"grade" -> 11, 
    "students" -> {<|"name" -> "bill", "age" -> 15|>, <|
       "name" -> "susan", "age" -> 16|>}|>, <|"grade" -> 12, 
    "students" -> {<|"name" -> "manuel", "age" -> 16|>, <|
       "name" -> "morris", "age" -> 17|>, <|"name" -> "jackie", 
       "age" -> 16|>}|>};

Problem 1 (solved): We want to pass over the entire school, assigning a grade to every student. The process is designed to be perfectly objective and remove any chance of favoritism by the teacher -- if the student's age is an even number, he or she gets an A-, otherwise a B+.

Solution: Query[All, All, All, <|#, "score" -> If[EvenQ@#["age"], "A-", "B+"]|> &]@sampleStructure

Problem 2 (unsolved): How might one assign grades on the basis of each student's age and grade, rather than just his or her age?

Problem 3 (unsolved): How might one add an additional Key ("teacher"→) at the top level of any grade that has more than two students, leaving other grades unchanged?

Thanks for any help.

POSTED BY: Michael Stern
Answer
4 months ago

This is a challenging question. I approached Question 2 by going through each grade separately. The first step selects all results from a grade level. Then I insert another Query function on the selected list of associations ("students"). This query function acts like yours above by inserting a grade based on a grade function defined below. Finally, I apply Join to merge the results from each grade level.

Join@@Table[
    Query[Select[#["grade"]==specGrade&],
       <|#,"students"->Query[All,<|#,"score"->grade2[specGrade,#["age"]]|>&][#["students"]]|>&
    ][sampleStructure]
    ,
    {specGrade,{11,12}}
]

My grading function was defined as this:

grade2[11,15]:="C+"
grade2[11,16]:="B-"
grade2[12,16]:="B+"
grade2[12,17]:="A-"
grade2[_,_]:="F"
POSTED BY: Chad Knutson
Answer
4 months ago

Group Abstract Group Abstract