'Using an iterator on a table

I have this table:

A:2.34889 2.484112 1.045939 3.359097 1.642348 1.298948 3.046995 4.077684 
B:3.845017 3.762336 3.287893 3.338063 5.861462 5.401914 3.537128 5.27197
t:([] AA:A;BB:B)

-1 + prd select (-1#AA)%(1#AA) from t 
-1 + prd select (-1#BB)%(1#BB) from t 

which outputs

AA| 0.7360047
BB| 0.3711175

I was wondering how I can modify the last two lines into a single line that iterates over AA and BB? For example, if I had 10 symbols, I would only have to write a single line to output the 10 results.

Also apologies on the question title, I am not sure how to phrase it well but am happy to edit if required.

kdb


Solution 1:[1]

Iterators on tables can either be row rise (demonstrated by 0N! below):

0N!/: t
`AA`BB!2.34889 3.845017
`AA`BB!2.484112 3.762336
`AA`BB!1.045939 3.287893
`AA`BB!3.359097 3.338063
`AA`BB!1.642348 5.861462
`AA`BB!1.298948 5.401914
`AA`BB!3.046995 3.537128
`AA`BB!4.077684 5.27197

Or column wise with flip:

0N!/: flip t
2.34889 2.484112 1.045939 3.359097 1.642348 1.298948 3.046995 4.077684
3.845017 3.762336 3.287893 3.338063 5.861462 5.401914 3.537128 5.27197

For this case, you could do the latter and apply your function to all columns with the each iterator:

{-1+prd last[x]%first x} each flip t
AA| 0.7360047
BB| 0.3711175

Use # or select to get the subset of columns you want to apply the function to if needs be:

{-1+prd last[x]%first x} each flip `AA`BB#t
AA| 0.7360047
BB| 0.3711175

More generally, when trying to build up similar code to apply to a list of columns functional form can be useful to be aware of: https://code.kx.com/q/basics/funsql/

parse "exec AA:{-1+prd last[x]%first x} AA from t"
?
`t
()
()
(,`AA)!,({-1+prd last[x]%first x};`AA)

// or cls:cols t
cls:`AA`BB ;

?[t;();();cls!({-1+prd last[x]%first x}),/:cls]
AA| 0.7360047
BB| 0.3711175

Solution 2:[2]

Matts answer is a better and more general answer but in your particular example the logic can be as simple as:

q)-1+last[t]%first t
AA| 0.7360047
BB| 0.3711175

Solution 3:[3]

No need to iterate through the columns.

The best use of iterators here is Each Left to apply both first and last to t.

q)(last;first)@\:t
AA       BB
-----------------
4.077684 5.27197
2.34889  3.845017

That table is a 2-list, so you can apply Divide.

q)-1+(%).(last;first)@\:t
AA| 0.7360047
BB| 0.3711175

To define this for re-use, it’s a composition of three unaries, here spaced for clarity:

q)f:-1+ (%). (last;first)@\:
q)f t
AA| 0.7360047
BB| 0.3711175

Works for any number of columns.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Matt Moore
Solution 2 terrylynch
Solution 3 SJT