kdb q - apply each-left for each atom in list and reduce

437 views Asked by At

I would like to apply each-left between a column of a table and each atom in a list. I cannot use each-both because the table column and the list are not of same length.

I have seen this done in one line somewhere already but I can't find it anymore..

Example:

t:([] name:("jim";"john";"john";"julia");c1: til 4);
searchNames:("jim";"john");
f:{[name;nameCol] nameCol like\:name}; / each-left between name (e.g. "jim") and column
g:f[;t[`name]];
r:g each searchNames; / result: (1000b;0110b)
filter:|/[r];     / result: 1110b
select from t where filter 

How can I do that more q-like?

2

There are 2 answers

0
Thomas Smyth - Treliant On BEST ANSWER

If you wish to use like with each-right /::

q)select from t where any name like/:searchNames
name   c1
---------
"jim"  0
"john" 1
"john" 2

In this case you can simply use in as you are not using any wildcards:

q)select from t where name in searchNames
name   c1
---------
"jim"  0
"john" 1
"john" 2
0
James Little On

Below is a generic function you could use, given two lists of different sizes.

q)f:{(|) over x like/:y}
q)
q)select from t where f[name;searchNames]
name   c1
---------
"jim"  0
"john" 1
"john" 2

Or, wrapping it up in a single function (assuming always searching a table column):

q)f2:{x where (|) over (0!x)[y] like/:z}
q)
q)f2[t;`name;searchNames]
name   c1
---------
"jim"  0
"john" 1
"john" 2

But in the scenario you describe, Thomas' solution seems the most natural.