解决您关于“我需要如何改变心态,以正确地在 q 中编程?”的最后一点:
您需要使用 over (/)、scan (\) 和 .zs 而不是使用循环。
例如,您的问题可以通过以下方式解决:(请注意,这些实际上并不是针对您的特定问题的最佳解决方案 - 索引是那里更好的方法 - 但尽管如此,下面的这些解决方案应该有助于理解这一点)
price:18.54 18.53 18.53 18.52 18.57 18.9 18.9 18.77 18.59 18.51 18.37
q)3#'{1_x}\[8;price]
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9 18.9
18.9 18.9 18.77
18.9 18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37
即遍历列表,每次切掉一个,每次迭代取前 3 个
或类似的
q)3#'{1 rotate x}\[8;price]
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9 18.9
18.9 18.9 18.77
18.9 18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37
即旋转 1 八次,每次旋转取前 3
使用 .zs 方法
q){$[2<count x;enlist[3#x],.z.s 1_x;()]}[price]
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9 18.9
18.9 18.9 18.77
18.9 18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37
即,如果还剩下至少 3 个元素,则先取 3 个元素,然后砍掉第一个元素并将相同的功能重新应用于缩短的列表。
在此示例中使用 over (/) 会很复杂,但通常 over 可用于替换“while”类型构造
i:0
a:0;
while[i<10;i+:1;a+:10]
更好地实现使用
q){x+10}/[10;0]
100
即添加 10,十次,起始(种子)值为零。
b:();
while[not 18~last b;b,:1?20]
即继续附加1到20之间的随机数,直到你达到18,然后停止。
更好地实现使用
q){x,1?20}/[{not 18~last x};()]
1 2 16 5 8 18
即在1到20之间附加一个随机数,只要检查函数返回true就迭代,从()开始作为种子值
使用 scan 和 over 还有许多其他选项,具体取决于您迭代的函数是否是 monadic/diadic 等。
作为一个广泛的概括:“for i=1:10”类型的循环可以在 q 中使用“function each i”来实现,“do”类型的循环可以在 q 中使用“function/[numOfTimes;seed]”来实现,使用“function/[booleanCheckFunction;seed]”可以在 q 中实现“while”类型的循环