この関数が何をするかを理解しようとしています:
yr:{ yr:.z.T+1000*x; -1 string .z.Z; while[(.z.T < yr); ZZ,::.z.Z]}
.zZ は日時を取得し、実行は右から左に行われることを理解しています。ZZとは?.zT とは何ですか?
本質的に、ラインは何を達成しますか?
より慣用的なものにするために、これをより適切に書き直したものがあります。のオーバーロードを利用\
して反復します。http://code.kx.com/q/ref/adverbs/#converge-iterateをご覧ください
あなたが持っている現在の関数は、現在の時間(.z.T
)を取り、秒数を追加しますx
(ミリ秒にするために1000を掛けます)。これが境界になり、現在の時刻がそれよりも短い限り、.z.Z
(日時マーカー) をグローバル リストに追加しますZZ
。
以下のバージョンは同じことを行いますが、いくつかの利点があります: グローバルの使用を避け、より慣用的なコードを記述します。
f2:{{.z.Z}\[{y; .z.T<x}.z.T+1e3*x; .z.Z]}
条件{y; .z.T<x}.z.T+1e3*x
が真である間、ループは繰り返されます。毎回再評価されないように、必ず外部から時間制限を渡すことに注意してください。さらにy
、反復の結果にこの条件を適用しようとするため、ダミー パラメータが必要ですが、それは.z.Z
. 反復するたびに.z.Z
、日時を返すことを評価します。使用していて使用\
していない/
ため、リスト全体が生成されます。
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 .......
そうは言っても、現在から現在 + x までの一連の日時値を生成しようとしている場合、これは最善の方法ではありません。.z.Z
スタンプは、マシンが実際にそれを評価するのにかかる時間を反映するからです。
訂正: 条件テストのラムダが である理由を正しく説明しませんでした{y; .z.T<x}.z.T+1e3*x
。あなた.z.T+1e3*x
が最初にのみ評価されることを確認したいので、あなたの境界が関数内にあることを望まない. さらに、y
param を省略した場合、{z.T<x}.z.T+1e3*x
すぐに false と評価され、ループの各サイクルでtype
反復結果を適用しようとするため、反復はエラーを返します。0b
保持y
して使用しないことで、この評価を遅らせ、境界を正しくテストするラムダを作成します。
.z.T
is the current time in the time
datatype; the underlying number in time
s is milliseconds since midnight, so adding 1000*x
gives a time x
seconds in the future.
-1 string .z.Z
prints the current datetime
to stdout
.
while[(.z.T < yr); ..]
loops as long as the current time is less than yr
(x
seconds in the future).
ZZ,::.z.Z
appends the current datetime
to a global variable named ZZ
.
some additional notes:
the datetime
datatype is in general deprecated in favor of timestamp
.
the parentheses around the test condition are redundant.
the second :
is also redundant, but for more interesting reasons: ,:
(like all of the two-argument "writeback" functions (x+:1
, y-:2
, etc.)) always modifies either a global or a local variable, depending on whether a local of that name exists in the function.
proof:
q)delete from`.;
q){ZZ:(); yr:.z.T+1000*x; -1 string .z.Z; while[(.z.T < yr); ZZ,::.z.Z]}1
2014.04.30T18:26:24.592
q)ZZ
'ZZ
q)
the ZZ
being modified inside the while loop in that version of the function was the local variable declared in the first statement, not a global one as one might assume given the presence of a ::
in the modification statement.
anyway, if you want to do it like this, it should at the very least be rewritten to yr:{ yr:.z.T+1000*x; -1 string .z.Z; while[.z.T < yr; ZZ,:.z.Z]}
.
この関数が行っていること:
この関数は 1 つのパラメーター (int である必要があります) を受け入れ、それらの秒数を現在の時間 (将来の時間としましょう) に追加します。次に、現在の時刻から未来の時刻へのループを開始し、反復ごとに現在の日付と時刻をグローバル リスト (変数 ZZ で参照) に追加します。
電話する方法:yr[2]
説明:
yr:.z.T+1000*x
.z.T
現在の現地時間を教えてください。
1000 は 1 秒に相当します。したがって、現在の時刻に x 秒を加算し、変数 yr に格納しています。( :
代入 (=) を意味します)
ZZ,::.z.Z
::
グローバル変数に何かを割り当てるために使用されます。リストZZ
(配列など)であるグローバル変数も同様です。
,
を追加するために使用されます。上記のステートメントは次と同等ですZZ : ZZ , .z.Z
.z.Z
現在の現地日時を与える。
while[(.z.T < yr);...]
これがループの条件です。そのため、現在の時刻 ( .z.T
) を取得し、最初のステートメントで計算された将来の時刻よりも小さいかどうかを確認します。
ループは、現在の時刻 =yr(将来の時刻) になると終了します。
ZZ
。