All functions

Appian a!forEach()

Run an expression once per item and collect the results. The function people reach for too early, because Appian already applies most things across a whole list on its own.

Official Appian documentation

The shape

a!forEach() takes a list and an expression, runs the expression once per item, and hands back a list of the results.

a!forEach(items: someList, expression: something(fv!item))

Inside the expression you get three things, and they are the reason to use it at all:

  • fv!item — the item this pass is working on
  • fv!index — its position, counting from 1, not 0
  • fv!isFirst and fv!isLast — true on the first and last pass

Most of the time you do not need it

This is the part worth learning first. Appian's operators and most of its functions already apply themselves to every item of a list on their own.

{1, 2, 3} * 10 gives you {10, 20, 30}. upper({"ann", "bo"}) gives you {"ANN", "BO"}. Neither needs a loop, and wrapping one around them is longer to read and no faster.

Reach for a!forEach() when the body needs something an operator cannot supply:

  • the item's position in the list
  • two or more fields of the same item combined together
  • a decision per item, usually an if()

It always returns a list

One item in, a list of one out. Pass it something that is not a list at all and it treats it as a list of one. The result is never a bare value, which matters the moment you feed it into something else.

Returning an empty list drops that item

An iteration that returns {} contributes nothing to the result. That is how filtering is written:

a!forEach(items: scores, expression: if(fv!item > 10, fv!item, {}))

The result is shorter than the input, which is the one case where the "same length out" rule does not hold. Read it as "keep this one, or nothing".

The trap worth knowing

Nesting one a!forEach() inside another gives the inner loop its own fv!item, and it hides the outer one. There is no fv!parent. If the inner expression needs the outer item, catch it in a local first:

a!forEach(
  items: rows,
  expression: a!localVariables(
    local!row: fv!item,
    a!forEach(items: columns, expression: local!row & fv!item)
  )
)

Try it

Run each one and read what comes back before moving on.

1Before writing a loop, see what happens without one. Multiply a whole list by 10.

{1, 2, 3} * 10

2Functions do it too. Uppercase a list of names.

upper({"ann", "bo"})

3Now ask for something an operator cannot give you: each item’s position.

a!forEach(items: {"tea", "pie"}, expression: fv!index & ". " & fv!item)

Pass something that is not a list at all.

a!forEach(items: 5, expression: fv!item)

Return {} for the items you do not want.

a!forEach(items: {4, 12, 7, 20}, expression: if(fv!item > 10, fv!item, {}))

Treat the last item differently from the rest.

a!forEach(items: {"a", "b", "c"}, expression: if(fv!isLast, fv!item & ".", fv!item & ", "))

Independent evaluator — approximates the Appian expression language and may differ from a real Appian environment. Verify anything that matters. Terms

Exercises

0 of 5 cleared
  1. 1a!forEach(): number a list of items
  2. 2a!forEach(): combine two fields from each record
  3. 3a!forEach(): list the invoices that need a reminder
  4. 4a!forEach(): mark the most recent entry
  5. 5a!forEach(): print the lines of an invoice
Start the first exercise