了解如何阅读 kdb 中的每右和每左组合

Understanding how to read each-right and each-left combined in kdb

来自 q for mortals,我正在努力理解如何阅读此内容,并从逻辑上理解它。

1 2 3,/:\:10 20

我知道结果是完整形式的叉积:raze 1 2 3,/:\:10 20

但是从左到右阅读,我目前无法理解这会产生什么(在我的脑海中)

\:10 20

结合1 2 3,/:??

帮助理解如何清楚地阅读本文(用文字或清晰的逻辑)将不胜感激。

当我在 q 中编写语法时,我发现自己在脑海中说了以下内容。 q 从右到左工作。

Internal Monologue ->  Join the string on the right onto each of the strings on the left
code ->                "ABC",\:"-D"
result ->              "A-D"
                       "B-D" 
                       "C-D"

我认为这是理解它的一种简单方法。 'join' 可以替换成任何...

Internal Monologue ->  Does the string on the right match any of the strings on the left
code ->                ("Cat";"Dog";"CAT";"dog")~\:"CAT"
result ->              0010b

每个权利都是相同的概念,将它们组合起来也很简单;

Internal Monologue ->  Does each of the strings on the right match each of the strings on the left
code ->                ("Cat";"Dog";"CAT";"dog")~\:/:("CAT";"Dog")
result ->              0010b
                       0100b   

因此在您的示例中 1 2 3,/:\:10 20 - 您说的是 'Join each of the elements on the right to each of the elements on the left'

希望对您有所帮助!!

编辑 添加一个现实世界的例子.... - 考虑以下 table

q)show tab:([] upper syms:10?`2; names:10?("Robert";"John";"Peter";"Jenny"); amount:10?til 10)
syms names    amount
--------------------
CF   "Peter"  8
BP   "Robert" 1
IC   "John"   9
IN   "John"   5
NM   "Peter"  4
OJ   "Jenny"  6
BJ   "Robert" 6
KH   "John"   1
HJ   "Peter"  8
LH   "John"   5
q)

我想得到名字是罗伯特的所有记录,你可以做; select from tab where names like "Robert"

但是,如果您想获得名称为 Robert 或 John 的结果,那么使用我们的 each-left 和 each-right 是一个完美的方案。

考虑名称列 - 它是一个字符串列表(每个元素都是字符列表的列表)。我们要问的是 'does any of the strings in the names column match any of the strings we want to find'... 翻译成 (namesList)~\:/:(list;of;names;to;find)。这是步骤;

q)(tab`names)~\:/:("Robert";"John")
0100001000b
0011000101b

根据该结果,我们需要一个已编译的布尔值列表,其中每个元素对 Robert OR John 都为真 - 例如,如果您查看两个列表的索引 1,Robert 为 1b,John 为 0b - 在我们的结果中,索引 1 处的值应为 1b。索引 2 应该是 1b,索引 3 应该是 1b,索引 4 应该是 0b 等等...为此,我们可以应用 any 函数(或 max 或 sum!)。结果就是;

q)any(tab`names)~\:/:("Robert";"John")
0111001101b

把它们放在一起,我们得到;

q)select from tab where any names~\:/:("Robert";"John")
syms names    amount
--------------------
BP   "Robert" 1
IC   "John"   9
IN   "John"   5
BJ   "Robert" 6
KH   "John"   1
LH   "John"   5
q)

首先,q 从右到左执行(因此通常是读取)。这意味着它将 \: 解释为应用于前一个函数的修饰符,它本身是由 /: 副词修饰的简单连接。所以读这个的方法是 "Apply join each-right to each of the left-hand arguments."

在这种情况下,您将两个副词应用于连接 - \:10 20 本身在这里没有实际意义。

我发现还可以查看代码生成 2x6 矩阵的相反情况 1 2 3,\:/:10 20、运行,我将其描述得更像 "apply join each-left to each of the right hand arguments" ... 我希望这是有道理的。

另一种可能有帮助的语法是 ,/:\:[1 2 3;10 20] - 这可能很有用,因为它非常清楚您正在应用的函数是什么,并且等同于您的就地表示法。