Iteration
The primary means of iteration in q are
- atomic functions
- the map iterators: Each and its variants
- the accumulating iterators Scan and Over
Atomic functions
Atomic functions apply to atoms in their arguments, and preserve structure to arbitrary depth.
Many of the q operators that take numerical arguments are atomic.
The arguments of an atomic function must conform: they must be lists with the same count, or atoms.
When an atom argument is applied to a list, it is applied to every item.
q)2 3 4 + 5 6 7 / same-count lists
7 9 11
q)2 + 3 4 5 / atom and list
5 6 7
This is called scalar extension. It applies at every level of nesting.
q)2+(3 4;`a`b`c!5 6 7;(8 9;10;11 12 13);14)
5 6
`a`b`c!7 8 9
(10 11;12;13 14 15)
16
Iterators
The iterators are unary operators. They take values as arguments and derive functions that apply them repeatedly.
Value
A applicable value is a q object that can be indexed or applied to one or more arguments:
- function: operator, keyword, lambda, or derived function
- list: vector, mixed list, matrix, or table
- dictionary
- file- or process handle
The iterators can be applied postfix, and almost always are.
For example, the Over iterator /
applied to the Add operator +
derives the function +/
, which reduces a list by summing it.
q)(+/)2 3 4 5
14
There are two groups of iterators: maps and accumulators.
Maps
The maps – Each, Each Left, Each Right, Each Prior, and Each Parallel – apply a map to each item of a list or dictionary.
q)count "zero" / count the chars (items) in a string
4
q)(count')("The";"quick";"brown";"fox") / count each string
3 5 5 3
Accumulators
The accumulators – Scan and Over – apply a value successively, first to the argument, then to the results of successive applications.
Control words
The control words if
, do
, and while
also enable iteration, but are rarely required.