https://learninghub.kx.com/forums/topic/each-both-creating-a-projection
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!
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 (‘) 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
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)
thank you so much for all the help! super clear explanation!