Kdb 在函数中,如何将值传递给内联子函数

Kdb 在函数中,如何将值传递给内联子函数,kdb,Kdb,在函数中,我做了如下操作: {3#x} each 7,8,9 / returns (7 7 7j;8 8 8j;9 9 9j) 以下代码失败(据我理解,因为lambda中未定义N): 我的解决方法是使用投影: foo:{ N: floor acos -1; {y#x}[;N] each x } 是否有更短或更整洁的解决方案?内部函数无法访问父函数变量。您需要显式地将所需的父变量传递给内部函数 在您的示例中,您可以通过将代码更改为使用“#”和: 提示:务必首先尝试使用KDB运算符和

在函数中,我做了如下操作:

{3#x} each 7,8,9
/ returns (7 7 7j;8 8 8j;9 9 9j)
以下代码失败(据我理解,因为lambda中未定义
N
):

我的解决方法是使用投影:

foo:{
  N: floor acos -1; 
  {y#x}[;N] each x  }

是否有更短或更整洁的解决方案?

内部函数无法访问父函数变量。您需要显式地将所需的父变量传递给内部函数

在您的示例中,您可以通过将代码更改为使用“#”和:


提示:务必首先尝试使用KDB运算符和副词实现您的逻辑。它们可以通过多种方式组合,以生成高效简单的代码。

内部函数无法访问父函数变量。您需要显式地将所需的父变量传递给内部函数

在您的示例中,您可以通过将代码更改为使用“#”和:


提示:务必首先尝试使用KDB运算符和副词实现您的逻辑。它们可以以多种方式组合在一起,以生成高效而简单的代码。

我认为问题的产生是因为q/kdb中缺乏所谓的“词汇范围”。这本质上意味着局部变量在同一范围内定义的局部函数体中不可见。此处的内部函数无法“查看”定义它的位置

也许更简洁的方法是如下

{(floor acos -1)#'x}[7 8 9]
否则,当您将局部变量作为参数传入时,您的变通方法工作得很好。注意到您正试图将“take”操作符应用于它正确的每个参数,因此您可以应用“each right”操作符/:,这可以稍微加快速度

q)\t:1000000 N:floor acos -1;f:{[N;x] N#/:x};f[N;7 8 9]
1308
q)\t:1000000 N:floor acos -1;{y#x}[;N]each 7 8 9
1835
这可以通过使用“each-both”操作符进一步优化,该操作符将成对计算take操作符的两个参数,扩展一个atom参数以匹配列表的长度

这就是Rahuls示例中发生的情况:

q)\t:1000000 foo:{#'[floor acos -1;x]};foo 7 8 9
1012

希望这能有所帮助。

我认为问题的产生是因为在q/kdb中缺乏所谓的“词汇范围”。这本质上意味着局部变量在同一范围内定义的局部函数体中不可见。此处的内部函数无法“查看”定义它的位置

也许更简洁的方法是如下

{(floor acos -1)#'x}[7 8 9]
否则,当您将局部变量作为参数传入时,您的变通方法工作得很好。注意到您正试图将“take”操作符应用于它正确的每个参数,因此您可以应用“each right”操作符/:,这可以稍微加快速度

q)\t:1000000 N:floor acos -1;f:{[N;x] N#/:x};f[N;7 8 9]
1308
q)\t:1000000 N:floor acos -1;{y#x}[;N]each 7 8 9
1835
这可以通过使用“each-both”操作符进一步优化,该操作符将成对计算take操作符的两个参数,扩展一个atom参数以匹配列表的长度

这就是Rahuls示例中发生的情况:

q)\t:1000000 foo:{#'[floor acos -1;x]};foo 7 8 9
1012

希望这有帮助。

正如Rahul和Liam所提到的,对于这个简单的例子,最好的方法是
采用
两种方法

在某些情况下,使用括号
()
创建简单的投影可以在保持相同易读性的同时工作。在您的示例中:

q){N:floor acos -1;(N#)each x}7 8 9
7 7 7
8 8 8
9 9 9

至于变量范围-非全局变量仅在函数的大括号
{}
内确定范围,如Rahul和Liam所述,对于这个简单的示例,最好的方法是
take
两种方法

在某些情况下,使用括号
()
创建简单的投影可以在保持相同易读性的同时工作。在您的示例中:

q){N:floor acos -1;(N#)each x}7 8 9
7 7 7
8 8 8
9 9 9

至于变量作用域-非全局变量仅在函数的大括号
{}
内作用域

为避免使用lambdas,可采用以下解决方案(基于Liam提供的上述解决方案):

(#[floor acos-1]@)每个7 8 9

这种格式有助于避免词汇范围的问题,因为它可以访问括号内括号外的变量。类似的说法是:

N:楼层acos-1;(#[N]@)每个7 8 9

人们可以进一步操纵括号内的结果,就像在函数中如何操作一样(因为括号中的“功能化”告诉口译员“操作”的适当顺序)


N:楼层acos-1;(1#[N]@)每个7 8 9

为了避免使用lambdas,可以采用以下解决方案(基于Liam提供的上述解决方案):

(#[floor acos-1]@)每个7 8 9

这种格式有助于避免词汇范围的问题,因为它可以访问括号内括号外的变量。类似的说法是:

N:楼层acos-1;(#[N]@)每个7 8 9

人们可以进一步操纵括号内的结果,就像在函数中如何操作一样(因为括号中的“功能化”告诉口译员“操作”的适当顺序)


N:楼层acos-1;(1#[N]@)每个7 8 9

都是
在这里要做的事?正确,这就是
()
在这里要做的事?正确,就是这样