The primary means of iteration in q are
- implicit in its operators and keywords
- the map iterator Each and its variants distribute evaluation through data structures
- the accumulating iterators Scan and Over control successive iterations, where the result of one evaluation becomes an argument to the next
- the control words
Most operators and keywords have iteration built into them.
A common beginner error is to specify iteration where it is already implicit
The iterators are unary operators. They take values as arguments and derive functions that apply them repeatedly.
An 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
- 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.
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
The accumulators – Scan and Over – apply a value successively, first to the argument, then to the results of successive applications.
The control words
while also enable iteration, but are rarely required.
Do as little as possible
First see if the iteration you want is already implicit in the operators and keywords.
If not, use the map and accumulator iterators to specify the iteration you need.
If you find yourself using the
while control words, you probably missed something.
“I’ll say no more than necessary. If that.”
— ‘Chili’ Palmer in Get Shorty.