我想维护一个列表L
。所以我想写一个函数func[]
,它总是取列表L
的最后一个表,处理它,返回一个附加到L
末尾的值。
例如:
设L
为[a,b,c]
func()
将取c
,计算d = func[c]
现在L
变成[a,b,c,d]
func()
将取d
,计算e = func[d]
现在L
变成[a,b,c,d,e]
等等。
如何在kdb/q中实现这一点?
Do or while应该允许您实现这一点,例如
q)l:0 2;f:{x,2*last x}
q)
q)5 f/ l // do op 5 times
0 2 4 8 16 32 64
q)
q)(64>last@) f/ l // perform op while last item in list is less than 64
0 2 4 8 16 32 64
我认为over函数正是您所需要的。https://code.kx.com/q/ref/over/
q)l:1 2 3
q)f:{if[100<count x;:x];x,1+last x}
q)over[f;l]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29..
我添加了一个条件来打破f中的循环。当使用over时,如果两次返回相同的结果,它将停止。
您也可以使用.z.s。这将使用新的输入重复当前函数。https://code.kx.com/q/ref/dotz/#zs-自
添加到@CWD的答案中,您可以使用.z.s
这样的显式递归:
func: {[x;f;threshold] $[threshold <= count x;x;.z.s [x,enlist f last x;f;threshold]]}
func[1 2 3;{x*10};5} /returns 1 2 3 30 300
这将递归地将函数应用于最后一个元素,直到列表的总计数达到指定的阈值。当然,将阈值设置得太高,最终会出现stack
错误。因此,最好在生产级代码中使用标准迭代器。