In q, I am trying to call a function f
on an incrementing argument id
while some condition is not met.
The function f
creates a table of random length (between 1 and 5) with a column identifier
which is dependent on the input id
:
f:{[id] len:(1?1 2 3 4 5)0; ([] identifier:id+til len; c2:len?`a`b`c)}
Starting with id=0
, f
should be called while (count f[id])>1
, i.e. so long until a table of length 1 is produced. The id
should be incremented each step.
With the "repeat" adverb I can do the while condition and the starting value:
{(count x)>1} f/0
but how can I keep incrementing the id
?
Not entirely sure if this will fix your issue but I was able to get it to work by incrementing id
inside the function and returning it with each iteration:
q)g:{[id] len:(1?1 2 3 4 5)0; id[0]:([] identifier:id[1]+til len; c2:len?`a`b`c);@[id;1;1+]}
In this case id
is a 2 element list where the first element is the table you are returning (initially ()
) and the second item is the id
. By amending the exit condition I was able to make it stop whenever the output table had a count of 1:
q)g/[{not 1=count x 0};(();0)]
+`identifier`c2!(,9;,`b)
10
If you just need the table you can run first
on the output of the above expression:
q)first g/[{not 1=count x 0};(();0)]
identifier c2
-------------
3 a
The issue with the function f
is that when using over and scan the output if each iteration becomes the input for the next. In your case your function is working on a numeric value put on the second pass it would get passed a table.