「qで正しくプログラミングするには、どうすれば考え方を変える必要がありますか?」についての最後のポイントに対処します。
ループを使用するのではなく、オーバー (/)、スキャン (\)、および .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
つまり、リストを反復し、毎回 1 つを切り捨て、各反復の最初の 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 を 8 回回転し、各回転の最初の 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 つを取得し、次に最初の項目を切り取り、短縮されたリストに同じ関数を再適用します。
この例ではオーバー (/) を使用すると複雑になりますが、一般的にオーバーは「while」型構造を置き換えるのに便利です
i:0
a:0;
while[i<10;i+:1;a+:10]
を使用するとよりよく達成されます
q){x+10}/[10;0]
100
つまり、開始 (シード) 値 0 で 10 を 10 回追加します。
b:();
while[not 18~last b;b,:1?20]
つまり、18 に到達するまで 1 から 20 までの乱数を追加し続け、その後停止します。
を使用するとよりよく達成されます
q){x,1?20}/[{not 18~last x};()]
1 2 16 5 8 18
つまり、1 から 20 までの乱数を追加し、() をシード値として開始して、チェック関数が true を返すまで繰り返します。
反復している関数がモナド/ダイアディックなどであるかどうかに応じて、スキャンとオーバーを使用するための他の多くのオプションがあります。
大まかに一般化すると、「for i=1:10」タイプのループは「function each i」を使用して q で実現でき、「do」タイプのループは「function/[numOfTimes;seed]」を使用して q で実現できます。 「function/[booleanCheckFunction;seed]」を使用して、「while」タイプのループをqで実現できます