There is a nicer rewrite of this to make it much more idiomatic. It takes advantage of the overload of \
to iterate. Check out http://code.kx.com/q/ref/adverbs/#converge-iterate
The current function you have, takes the current time (.z.T
) and adds x
number of seconds (it multiplies by 1000 to make it milliseconds). This becomes your bound, and then as long as the current time is less than that, you append .z.Z
(the datetime marker) to a global list ZZ
.
The version below will do the same with a couple advantages:you avoid using a global and you write more idiomatic code
f2:{{.z.Z}\[{y; .z.T<x}.z.T+1e3*x; .z.Z]}
While your condition {y; .z.T<x}.z.T+1e3*x
is true, your loop will continue to iterate. Note that we make sure to pass in the time limit from outside, so that it is not revaluated it each time, additionally we need a dummy parameter y
, as it will try to apply this condition to the result of our iteration, but we don't really want that, since that is .z.Z
. Each time it iterates it will evaluate .z.Z
returning the datetime. Since you are using \
and not /
you will get the entire list generated.
q)f2:{{.z.Z}\[{y; .z.T<x}.z.T+1e3*x; .z.Z]}
q)f2 1
2014.04.30T17:40:23.357 2014.04.30T17:40:23.357 .......
That being said, if you're looking to generate a sequence of datetime values, from now to now+x, this is not the best way to do that, since your .z.Z
stamp will reflect the time it takes your machine to actually evaluate that.
CORRECTION:
I did not correctly explain the reason our condition testing lambda is {y; .z.T<x}.z.T+1e3*x
. You want to make sure your .z.T+1e3*x
is only evaluated at the start, so you do not want your bound to be inside the function. Additionally, if you were to leave out the y
param, then {z.T<x}.z.T+1e3*x
would immediately evaluate to false, and your iteration would return a type
error as it tries to apply your iteration result to 0b
at each cycle of the loop. By keeping y
and just not using it, we make sure to delay this evaluation and create a lambda that correctly tests our bound.