0

In q/kdb, we can apply a function to a number of arguments, as below:

f each (1;2;3)

We can also apply a defined argument to a list of functions:

flist: (f1:{x+y+z},f2:{x+y-z},f3:{x-y+z});
flist  .\: 1 2 3

What is the most efficient way to combine both of these- to apply every function in a list to each value in a list as parameters. For example, to apply 3 unary functions, f1, f2 and f3, to a list containing values 1, 2 and 3 (producing 9 calls).

Any help with this is much appreciated!

Will Da Silva
  • 6,386
  • 2
  • 27
  • 52

2 Answers2

2

You can use the eachboth (') operator:

q)f1:1+;f2:2+;f3:3+
q)(f1;f2;f3) @' 10 20 30
11 22 33

or in the case of multi-argument functions,

q)g1:+;g2:-;g3:*
q)(g1;g2;g3) .' (2 1;3 2;2 2)
3 1 4

and if you want to apply each function to each value, you need to form a cross product first:

q)(@/)each(f1;f2;f3) cross 10 20 30
11 21 31 12 22 32 13 23 33
Alexander Belopolsky
  • 2,228
  • 10
  • 26
  • If we want to apply each function to each value, how would we go about that? For example, if we want the following to insert both values into both lists?: `.abc.list:(); .abc.list2:(); f1:{[aircraft].abc.list,:aircraft}; f2:{[aircraft].abc.list2,:aircraft}; (f1;f2) @' (exec distinct sym from data)` – StackPro_1111 Oct 29 '20 at 17:10
  • I updated my answer, but @james-little suggestion to use `@/:\:` is probably better. – Alexander Belopolsky Oct 29 '20 at 17:12
  • Your answer is on the money too- thank you for your help! – StackPro_1111 Oct 29 '20 at 17:21
1

You can use the unary apply-at @ (since you are dealing with unary functions), in combination with each-left & each-right. For example:

q)({x+1};{neg x};{x*x}) @\:/: (1 2 3)
2 -1 1
3 -2 4
4 -3 9
James Little
  • 1,964
  • 13
  • 12