传递符号列表至Kdb+函数参数时遇列表长度不兼容问题求助
Kdb+ condSel函数多列过滤报错问题修复
我写了一个用来过滤主表的Kdb+函数condSel,代码如下:
condSel:{[tabl;colNames;colValues] wc: {(in;x;enlist y)}.'flip(colNames;colValues); res: ?[tabl;wc;0b;()]; res }
单独对主表的单个列过滤时能正常执行:
res_fltr1: condSel[t;enlist `s; enlist `s1]; res_fltr2: condSel[t;enlist `name; enlist `$("P Willy";"D Reim")];
但同时组合两个列过滤时,会收到列表长度不兼容的错误,不知道怎么修复:
res_fltr: condSel[t;`s`name;`s1`$("P Willy";"D Reim")];
奇怪的是,如果换成s和p列,每个列传单个符号就没问题:
res_fltr: condSel[t;`s`p;`s1`p1];
示例表结构及数据如下:
s p qty name ------------------ s1 p1 300 F James s1 p2 200 P Willy s1 p3 400 P Willy s1 p4 200 D Reim s4 p5 100 M Oxhart s1 p6 100 P Willy ...
问题原因
出错的核心是colValues的结构不匹配。当你写s1$("P Willy";"D Reim")时,得到的是(s1;(P Willy;D Reim))——第二个元素是包含两个值的列表,而colNames是长度为2的符号列表(s;name)。用flip组合时,colNames的每个元素需要对应colValues`的单个元素,但第二个元素是列表,导致维度不兼容触发报错。
而s和p列能正常运行,是因为colValues的每个元素都是单个符号,和colNames长度完全匹配,flip后能正确配对生成过滤条件。
修复方案
需要保证colValues的每个元素都是对应列要过滤的值列表,哪怕是单个值也要统一结构,以下两种方案都可以解决:
方案1:调整调用时的参数格式
把单个值的列用enlist包裹,确保colValues的每个元素都是列表:
// 写法1 res_fltr: condSel[t;`s`name;enlist`$s1;enlist`$("P Willy";"D Reim")]; // 写法2(更简洁的列表形式) res_fltr: condSel[t;`s`name;(`s1;`$("P Willy";"D Reim"))];
方案2:修改函数自动兼容单个值
在函数内部自动把单个值转为单元素列表,避免调用时的格式限制:
condSel:{[tabl;colNames;colValues] // 统一格式:单个值转成单元素列表 colValues: enlist each colValues; wc: {(in;x;y)}.'flip(colNames;colValues); ?[tabl;wc;0b;()] }
修改后不管传单个值还是多值列表都能正常运行,比如:
// 单列单个值 condSel[t;enlist `s;`s1]; // 单列多个值 condSel[t;enlist `name;`$("P Willy";"D Reim")]; // 多列混合单个/多个值 condSel[t;`s`name;`s1;`$("P Willy";"D Reim")];
内容的提问来源于stack exchange,提问作者vicefreak04
相关产品推荐
相关产品推荐

