解释Q代码行

时间:2014-04-18 05:30:06

标签: kdb q-lang

试图了解这个功能的作用:

yr:{ yr:.z.T+1000*x; -1 string .z.Z; while[(.z.T < yr); ZZ,::.z.Z]}

我明白.z.Z获取日期时间,执行是从右到左。什么是ZZ?什么是.z.T?

基本上,这条线完成了什么?

4 个答案:

答案 0 :(得分:1)

  • 此处::表示将右侧的值分配给全局变量 左边
  • ZZ是全局变量
  • ZZ,::。z.Z是ZZ :: ZZ,.z.Z的简写 因此,它将最新时间附加到全局变量ZZ。

e.g。

q)f:{ZZ,::2}
q)f[]
q)ZZ
,2
q)f[]
q)ZZ
2 2

.z.T是时候。

答案 1 :(得分:1)

有一个更好的改写,使其更加惯用。它利用\的重载来迭代。查看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标记将反映它的时间让你的机器实际评估它。

校正: 我没有正确解释我们测试lambda的条件是{y; .z.T<x}.z.T+1e3*x的原因。您希望确保仅在开始时评估.z.T+1e3*x,因此您不希望绑定在函数内部。此外,如果您遗漏了y参数,那么{z.T<x}.z.T+1e3*x将立即评估为false,并且当您尝试将迭代结果应用于{时,您的迭代将返回type错误{1}}在循环的每个循环中。通过保留0b而不使用它,我们确保延迟此评估并创建一个正确测试我们边界的lambda。

答案 2 :(得分:1)

  • .z.Ttime数据类型中的当前时间; time s中的基础数字是自午夜以来的毫秒数,因此添加1000*x将来会有x秒的时间。

  • -1 string .z.Z将当前datetime打印到stdout

  • while[(.z.T < yr); ..]循环,只要当前时间小于yr(将来x秒)。

  • ZZ,::.z.Z将当前datetime附加到名为ZZ的全局变量。

一些额外的说明:

datetime数据类型通常已被弃用,有利于timestamp

测试条件周围的括号是多余的。

第二个:也是多余的,但出于更有趣的原因:,:(就像所有的两个参数&#34;回写&#34;函数(x+:1,{ {1}}等))总是修改全局变量或局部变量,具体取决于函数中是否存在该名称的本地变量。

证明:

y-:2

在该函数版本的while循环中被修改的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) 是在第一个语句中声明的局部变量,而不是一个全局的,因为如果存在ZZ,可能会假设修改声明。

无论如何,如果你想这样做,至少应该重写为::

答案 3 :(得分:0)

此功能正在做什么:
这个函数接受一个参数(应该是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) 并检查它是否小于计算的未来时间 在第一个声明中。

  • 循环将在当前时间=年(未来时间)结束。

  • 最后,您将拥有可以使用变量访问的全局列表 ZZ