Search code examples
kdb

changing value of specific row in table with conditions


let's assume I have below table.

    t:([]date:5#.z.D; ric:`A.HK`B.HK`C.HK`D.KS`E.T);

From here, I want to remove the trailing string, including "." if certain conditions are met.

Below are the way that I have been doing- but I was wondering if there would be much efficient/faster way.

     newriclist: exec distinct ric from t;
     dummy:{ (`ric`newric)!(x; `$ssr[string[x]; ".KS"; ""]) } each newriclist;
     t lj `ric xkey dummy ...

Or, this is what I want to ideally achieve, but it doesn't seem to work.

    update ric:?[string[ric] like "*.KS"; `$ssr[string[ric]; ".KS"; ""]; ric] from `t;

Solution

  • Using your table from above, you can do simply:

    q)update first each ` vs/:ric from `t where ric like "*.KS"
    `t
    q)t
    date       ric
    ---------------
    2018.02.24 A.HK
    2018.02.24 B.HK
    2018.02.24 C.HK
    2018.02.24 D
    2018.02.24 E.T
    

    For some explanation, this uses the fact you can do

    q)` vs `sym.suf
    `sym`suf
    

    to break down your syms into the dotted components without having to string. This needs to be applied each-right (/:) to operate on the affected column elements. This would return a list of lists, so first each takes care of turning it back into a simple list. The where condition here takes care of making sure it only operates on the correct syms.

    As a quick extension, if you're doing this to a big table with a lot of duplicate syms, using .Q.fu will operate more efficiently over multiple duplicate items in the list:

    update .Q.fu[{first each ` vs/:x};ric] from `t where ric like "*.KS"