5/5

where(): split a class into passed, failed and absent

Hard

After an exam the teacher wants the class split into three lists of names, each in class order. Each student is a record with a name and a score; a student who was absent has a null score.

Return a record with three fields

  • passed — scored at least ri!passMark
  • failed — sat the exam and scored below it
  • absent — no score

Watch out

  • A score of 0 is a fail, not an absence.
  • An absent student must not land in failed, so check what a comparison does with a null before relying on it.
  • isnull() given a whole list asks whether the list itself is null, not each score.

Tip: the names and the scores are each needed more than once. a!localVariables() lets you name them; repeating the expression works too.

Inputs

  • ri!students — List of Map
  • ri!passMark — Integer

ri! Rule Inputs

ri!studentsList of Map
{
  a!map(name: "Ann", score: 72),
  a!map(name: "Bo", score: 45),
  a!map(name: "Cy", score: null),
  a!map(name: "Di", score: 60)
}
ri!passMarkInteger
60

Example 1 — A mixed class

Input: ri!students
{
  a!map(name: "Ann", score: 72),
  a!map(name: "Bo", score: 45),
  a!map(name: "Cy", score: null),
  a!map(name: "Di", score: 60)
}
Input: ri!passMark
60
Output:
a!map(passed: {"Ann", "Di"}, failed: {"Bo"}, absent: {"Cy"})

Example 2 — Everyone passed

Input: ri!students
{
  a!map(name: "Ann", score: 90),
  a!map(name: "Bo", score: 81)
}
Input: ri!passMark
50
Output:
a!map(passed: {"Ann", "Bo"}, failed: {}, absent: {})

Example 3 — A score of 0 is a fail

Input: ri!students
{
  a!map(name: "Ed", score: 0),
  a!map(name: "Fa", score: null)
}
Input: ri!passMark
40
Output:
a!map(passed: {}, failed: {"Ed"}, absent: {"Fa"})

Example 4 — Everyone absent

Input: ri!students
{
  a!map(name: "Gu", score: null),
  a!map(name: "Ha", score: null)
}
Input: ri!passMark
60
Output:
a!map(passed: {}, failed: {}, absent: {"Gu", "Ha"})

Example 5 — An empty class

Input: ri!students
{}
Input: ri!passMark
60
Output:
a!map(passed: {}, failed: {}, absent: {})

Appian Expression Tips

  • • Use ri!variableName for rule inputs
  • • Use a!localVariables(local!x: …, body) for locals
  • • Use a!forEach(items: …, expression: fv!item) to iterate
  • • Use where() / reject(fn!isnull, list) to filter