kdb+

kdb+q @与. 的使用

2019-04-04  本文已影响206人  骑猪闯天下的狂奔的蚂蚁

说起kdb中的符号, @与. 绝对是里面最重要的两个之一。关于这两个符号的使用,在天书里是成批出现,两个的含义基本相似只有小许的区别,可以类比使用。
本文的主要内容来源于官网链接:
https://code.kx.com/mediawiki/index.php/JB:QforMortals2/functions#Functional_Forms_of_Amend
https://code.kx.com/mediawiki/index.php/Reference/trap
本文主要包括下面内容:

 1. 作为动词使用
 2. @与 . 结合二元函数函数使用(Dyadic Functions) 
 3. @与 . 结合一元函数使用(Monadic Functions) 
 4. 作为Trap使用。也就是其他语言的Try Catch。 

1. 作为动词使用:

我们先要了解一个事情就是数组和函数其实本质上是一样的东西,例子如下:

       L:(1 2;3 4 5; 6)
        L[0]
1 2
        L[0 2]
1 2
6
        L 0 2
1 2
6
        L[1;2]
5
        f:{x*x}
        f[0]
0
        f[0 2] //传入的x是一个数组。
0 4
        f 0 2
0 4
        g:{x+y}
        g[1;2]
3

它们都是用[]传入参数而已。。。。
有了这样的认识,后面就好办了。
L@0 与L[0] 等价。
L@0 2 与 L[0 2] 等价。
f@0 与 f[0] 等。
f@0 4 与 f[0 4] 等价 。
同样的对于字典,表格,有键值表格也都是一样的,类比即可所以@ 与[]是一样的意思,更多例子如下:

     d:`a`b`c!10 20 30
        d@`b
20

        t:([]c1:1 2 3; c2:`a`b`c)
        t@1
c1| 2
c2| b

        kt:([k:`a`b`c]f:1.1 2.2 3.3)
        kt@`c
f| 3.3

但是点(.)就不同了。

L@0 2  //返回  
1 2
6

L . 1 2 //返回
5   //记住L:(1 2;3 4 5; 6) ,所以.的意思就是定位到索引[1;2]然后把那个元素拿出来。


g . 1 2        // 所以在这里.的意思是吧数组1 2 转为g的第一个参数和第二个参数分别穿进去。
3 

所以对于数组点的意思就是定位到索引[1;2]然后把那个元素拿出来。
对于函数,点的意思就是把数组转为参数穿进去。
更多例子见下面:

        L1:(1;2 3;(4; 5 6))
        L1 . 2 1 1
6

        L2:(1;2 3;`a`b!(4;5 6))
        L2 . (2;`b;1)
6
     dd:`a`b`c!(1 2;1.1 2.2 3.3;`aa`bb!10 20)
        dd . (`a;1)
2
        dd . (`c`bb)
20

    t:([]c1:1 2 3;c2:`a`b`c)
        t . (1;`c2)
`b

2. @与.结合二元函数函数使用(Dyadic Functions)

@函数格式如下:

 @[L;I;f;y]

第一个参数是一个类似list,数组,表格,字典啥的,表格包括物理表和内存表。。。
第二个参数是第一个参数的索引,如果是字典就是键值,
第三个参数是二元函数f;f的第一个参数是L[I] ;f的第二个参数是y。
所以这个形式也可以有如下的等价写法:

 L[I] f y   //把第一个参数写在左边,实际上应该不行。
f[L[I];y]
//或者: 记住@ 与[]是等价的。
(L@I) f y
f[L@I;y]

使用例子如下:

L:100 200 300 400
 I:1 2
@[L;I;+;42 43]
100 242 343 400
    @[L;I;:;42 43]                                        //这种情况下L没更新,返回的是更新后的。
100 42 43 400
   L
100 200 300 400
@[`L;I;:;42]                / update L 直接更新L
`L
        L
100 42 42 400

    d:`a`b`c!10 20 30
        @[d;`a`c;+;9]
a| 19
b| 20
c| 39
        t:([] c1:`a`b`c; c2:10 20 30)
        @[t;0;:;(`aa;100)]
c1 c2
------
aa 100
b  20
c  30

点函数格式如下:

.[L;I;f;y]

与上面一样,可比较。

(L . I) f y     / binary operator
f[L . I;y]      / dyadic function

使用方法结合之前所讲也很容易理解:

  L:(100 200;300 400 500)
        I1:1 2
        I2:(1;0 2)
        .[L;I1;+;42]
100 200
300 400 542
        .[L;I2;+;42 43]
100 200
342 400 543

  .[L;I2;:;42 43]                      //这种情况下L没更新,返回的是更新后的。
100 200
42 400 43

   L
100 200
300 400 500
     L:(100 200;300 400 500)
        .[`L;I1;:;42]                / update L 直接更新L
`L
        L
100 200
300 400 42

   d:`a`b`c!(100 200;300 400 500;600)
        .[d;(`b;1);+;42]
a| 100 200
b| 300 442 500
c| 600

3. @与. 结合一元函数使用(Monadic Functions)

@与一元函数结合的形式如下:
@[L;I;f]

跟上面一样,我们也可以用下面表示更接地气。只是把上面的f从二元函数换为1元函数而已。

 f L[I]                / written as unary verb
 f[L[I]]                / written as mondaic function
 f[L@I]

例子:

 L:101 102 103
        I:0 2
        @[L;I;neg]
-101 102 -103

  d:`a`b`c!10 20 30
    @[d;`a`c;neg]
a| -10
b| 20
c| -30

点(.)与一元函数结合的形式如下:
 .[L;I;f]

更通俗如下:

 f[L . I]

例子:

 L:(100 200;300 400 500)
        I:1 2
        .[L;I;neg]
100 200
300 400 -500

d:`a`b`c!(100 200;300 400 500;600)
        .[d;(`b;1 2);neg]
a| 100 200
b| 300 -400 -500
c| 600
4.作为Trap使用。也就是其他语言的Try Catch。

@与点(.)的第一个参数是函数,第二个参数是第一个函数的参数,第三个参数是如果执行该函数失败就返回后面的第三个参数,至于区别就是执行函数的参数传递方式是@还是点的方式,如果是@只能传一个参数(就是中间那个参数)
例子:

q)@[string;42;`err]
"42"
.[*;(42;42);`err]
1764
q)@[{x+1};`aa;`err]
`err
.[{x+y};(1;2);`err] //第一个参数传给x,第二个参数传给y
3
q)@[{x[0]+x[1]};(1;2);`err]       //如果想用@又想传多个参数只能这样写。
3
上一篇下一篇

猜你喜欢

热点阅读