cancel
Showing results for 
Search instead for 
Did you mean: 

each-both creating a projection

kdb_newbie
New Contributor II

Hi Community,
If I have a function takes 3 inputs where I want to set the 3rd argument to be `field and I want to iterate over 2 lists using each-both, but the below creates a projection:
{.my.func[x;y;`field]} ' [value exec col1, col2 from tab1]
Would you help understand why please? Thank you!

2 ACCEPTED SOLUTIONS

davidcrossey
Moderator Moderator
Moderator

Your usage of square brackets has created the projection on the right-hand side, which is expecting an x argument:

q).my.func:{[x;y;z] (x;y;z)}
q)tab
col1 col2
---------
a    1
b    2
c    3

/ projection
q){.my.func[x;y;`field]}'[flip value exec col1,col2 from tab]
{.my.func[x;y;`field]}'[((`a;1);(`b;2);(`c;3))]
q)type {.my.func[x;y;`field]}'[flip value exec col1,col2 from tab]
104h

/ right-hand side projection; note .' as type ('[x]) will return 106
q)type .'[flip value exec col1,col2 from tab]
104h

/ using apply-each without square brackets
q)type {.my.func[x;y;`field]}.'flip value exec col1,col2 from tab
0h
q){.my.func[x;y;`field]}.'flip value exec col1,col2 from tab
`a 1 `field
`b 2 `field
`c 3 `field

Note the usage of apply-each .'

Here is a simplier example of your projection syntax:

/ missing x arg
q)@'[1 2]
@'[1 2]
q)type @'[1 2]
104h

/ providing x arg 
q)@'[10+;1 2]
11 12
q)type @'[10+;1 2]
7h

Hope this helps

 

View solution in original post

cillianreilly
New Contributor III

The exec statement creates a list of lists - enclosing these in square brackets means kdb+ treats this as a singular item passed to your function.  In order to treat the list as the first and second arguments respectively, you need apply:

 

q)tab:([]col1:`a`b`c;col2:1 2 3)
q).my.func:{0N!(x;y;z);}
q){.my.func[x;y;`field]}./:flip value exec col1,col2 from tab;
(`a;1;`field)
(`b;2;`field)
(`c;3;`field)

 

In this case though, you can keep the entire operation contained in the qsql statement. kdb+ will extend the atomic symbol to match the length of the table columns:

 

q)exec .my.func'[col1;col2;`field]from tab;
(`a;1;`field)
(`b;2;`field)
(`c;3;`field)

 

 

View solution in original post

3 REPLIES 3

davidcrossey
Moderator Moderator
Moderator

Your usage of square brackets has created the projection on the right-hand side, which is expecting an x argument:

q).my.func:{[x;y;z] (x;y;z)}
q)tab
col1 col2
---------
a    1
b    2
c    3

/ projection
q){.my.func[x;y;`field]}'[flip value exec col1,col2 from tab]
{.my.func[x;y;`field]}'[((`a;1);(`b;2);(`c;3))]
q)type {.my.func[x;y;`field]}'[flip value exec col1,col2 from tab]
104h

/ right-hand side projection; note .' as type ('[x]) will return 106
q)type .'[flip value exec col1,col2 from tab]
104h

/ using apply-each without square brackets
q)type {.my.func[x;y;`field]}.'flip value exec col1,col2 from tab
0h
q){.my.func[x;y;`field]}.'flip value exec col1,col2 from tab
`a 1 `field
`b 2 `field
`c 3 `field

Note the usage of apply-each .'

Here is a simplier example of your projection syntax:

/ missing x arg
q)@'[1 2]
@'[1 2]
q)type @'[1 2]
104h

/ providing x arg 
q)@'[10+;1 2]
11 12
q)type @'[10+;1 2]
7h

Hope this helps

 

cillianreilly
New Contributor III

The exec statement creates a list of lists - enclosing these in square brackets means kdb+ treats this as a singular item passed to your function.  In order to treat the list as the first and second arguments respectively, you need apply:

 

q)tab:([]col1:`a`b`c;col2:1 2 3)
q).my.func:{0N!(x;y;z);}
q){.my.func[x;y;`field]}./:flip value exec col1,col2 from tab;
(`a;1;`field)
(`b;2;`field)
(`c;3;`field)

 

In this case though, you can keep the entire operation contained in the qsql statement. kdb+ will extend the atomic symbol to match the length of the table columns:

 

q)exec .my.func'[col1;col2;`field]from tab;
(`a;1;`field)
(`b;2;`field)
(`c;3;`field)

 

 

kdb_newbie
New Contributor II

thank you so much for all the help! super clear explanation!