如何迭代多价等级(> 1)的函数,例如f:{[x;y] ...}
下一个迭代步骤中输入的函数取决于最后一个迭代步骤? the reference manual中的示例仅迭代一元函数。
我能够通过将参数字典(状态)传递给一元函数来间接地(冗长地)实现这一点:
f:{[arg] key[arg]!(min arg;arg[`y]-2)}
f/[{0<x`x};`x`y!6 3]
请注意投影,例如f[x;]/[whilecond;y]
仅在以下情况下才起作用:x
在下一个迭代步骤中 不 取决于上一次迭代的结果(即何时x与路径无关)。
答案 0 :(得分:2)
关于Rahul的答案,您可以使用以下一种方法(略为冗长)来达到相同的结果:
q)g:{(min x,y;y-2)}
q)(g .)/[{0<x 0};6 3]
-1 -3
q).[g]/[{0<x 0};6 3]
-1 -3
或者,您可以使用.z.s self函数,该函数递归调用函数g并将上次迭代的输出作为其参数。例如,
q)g:{[x;y] x: min x,y; y:y-2; $[x<0; (x;y); .z.s[x;y]]}
q)g[6;3]
-1 -3
答案 1 :(得分:1)
与'/'和'\'一起使用的函数只能将最后一次迭代的结果作为单个项接受,这意味着仅为该结果保留一个函数参数。从这个意义上说,它是一元的。
对于多个输入参数取决于上次迭代结果的函数,一种解决方案是将该函数包装在一元函数中,并使用apply运算符在上次迭代结果上执行该函数。
例如:
q) g:{(min x,y;y-2)} / function with rank 2
q) f:{x . y}[g;] / function g wrapped inside unary function to iterate
q) f/[{0<x 0};6 3]
答案 2 :(得分:0)
随着时间的流逝,我偶然发现了更短的方法,不需要括号或括号:
q)g:{(min x,y;y-2)}
q){0<x 0} g//6 3
-1 -3
为什么双重over
(//
)起作用?有时可以使用/
副词代替.
(apply
)运算符:
q)(*) . 2 3
6
q)(*/) 2 3
6