Search code examples
kdb+q

Return value from list of list when criteria met in KDB


I have a list of list which has 4 columns. Now I want to iterate over each list in list of list to find the first list which has say value ABC for first column and value XYZ for 3rd col. If this criteria satisfy I want to get out of the loop and return what was in 4th col. E.g of how list would look like below.

`AAA 23 `BBB  value
`AAA 23 `CCC  value
`ABC 23 `XYZ  value
`BBB 23 `CCC  value
......
..... 

I tried to do something like below, but this does not seem to work.

myfunc:{if [x[0] =`ABC and x[2]=`XYZ ; val:x[3] ; 'break ] } 

@[myfunc;x; if [x[0] =`ABC and x[2]=`XYZ; :x[3]]] each ListOfList

Note that i do not want to traverse whole of list of list as it has millions of list in it, and is interested in fetching value of first list where criteria is matched.


Solution

  • If all the list within the list has at least 4 entries then it might be more efficient to perform a vector comparison rather than using an iterator.

    See: https://code.kx.com/q4m3/3_Lists/#310-elided-indices

    list[;3]where(list[;0]=`ABC)&list[;2]=`XYZ / to get all the matching entries
    list[;3]first where(list[;0]=`ABC)&list[;2]=`XYZ / to get only the first match
    

    If you want to use a while loop:

    {while[not[`ABC`XYZ~x[0:0 2]]&count x;x:1_x];x[0;3]}list
    

    In your solutions, there are a few syntax errors.

    • In myfunc, if statement is not explicitly returning anything.
    • Your checks are wrong. The condition on the left needs to be bracketed as KDB evaluates from right to left.
    • Your second line is not wrapped into a function hence you are getting an 'x error. Even so, the error trap wouldn’t really return a value.