// keytable/dict operations / show utility show_:{[t] / show if[~&/0>4::'t[] / if not a table :((-|/#:'$k)$k:!t),'" : ",/:5::'t[]] / use dict display i:*|^t[] / count j:@[t;_n;(1|i)#] / empty f:{:[4:x;x;1_,/" ",x]} / nested k:f''+$+j[] / data l:+,$!j / labels m:1 -1@-4=4::'t[] / data justifications n:(|/#:')'l,'k / widths l:" ",''(-n)$l / padded labels k:" ",''(m*n)$k / padded data o:+," ",'n#'"-" / separators p:,'/l,'o,'k / result p} / matrix show:{`0:,," ";`0::[5 5~4::'x;{x,'" ",'@[(#x)#"|";1;:;"-"],'y}. show_'x;show_ x]} / k set (upsert) kset_:{:[5=4:x;kset_d;kset_t][x]y} kset_d:{[d;e]@[d;!e;:;e[]]} kset_t:{[t;u] td:*t;tr:t 1;ud:*u;ur:u 1 / domain and range of t and u uk:+ud[];tk:+td[] / keys of t and u if[#i:&b:uk _lin tk / what to amend tr[!ur;tk?/:uk i]:ur[;i]] / amend if[#j:&~b / what to append (u must be complete!) td[],:ud[;j] tr[],:ur[;j]] (td;tr)} / k delete kdel_:{:[5=4:x;kdel_d;kdel_t][x]y} kdel_d:{[d;k] dk:!d;dv:d[] i:&~dk _lin k .+(dk i;dv i)} kdel_t:{[t;d] td:*t;tr:t 1 k:+d[];tk:+td[] i:&~tk _lin k / what to keep td:@[td;_n;@[;i]] tr:@[tr;_n;@[;i]] (td;tr)} / k get kget_:{:[5=4:x;kget_d;kget_t][x]y} kget_d:{[d;k] dk:!d;dv:d[] i:&dk _lin k .+(dk i;dv i)} kget_t:{[t;d] td:*t;tr:t 1 k:+d[];tk:+td@!d i:&tk _lin k / what to return td:@[td;_n;@[;i]] tr:@[tr;_n;@[;i]] (td;tr)} / t -> kt, kt -> t, kt1 -> kt2 key:{[t;k](.+(k;t k);t _di k:(),k)} unkey:{[t].,/.:'t} rekey:{[t;k]key[unkey t]k} td:.+(`j`k;(1 1 2;`a`b`a)) tr:.+(`f`g`h;3 3#!9) show t:(td;tr); show d:.+(`j`k;(1 3 2;`a`x`a)) show kget_[t]d; ud:.+(`j`k;(1 2 3;`b`c`d)) ur:.+(`f`g`h;+(100 200 300;-1 -2 -3;-4 -5 -6)); show u:(ud;ur); show t2:kset_[t]u; show kdel_[t2]u 0; show kget_[t]u 0;