'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.
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 |
