KDB+/Q:单行表和多行表的输入不可知函数

KDB+/Q:Input agnostic function for single and multi row tables

我尝试使用以下函数派生一个 table 由 3 列组成,其中一列 data 包含任意模式的列表。

fn:{
   flip `time`data`id!(x`b;(x`a`b`c`d`e);x`a)
 };

这对多行输入效果很好,即:

q)x:flip `a`b`c`d`e!(5#enlist 5?10)
q)fn[`time`data`id!(x`b;(x`a`b`c`d`e);x`a)]

time data      id
-----------------
8    8 5 2 8 6 8
5    8 5 2 8 6 5
2    8 5 2 8 6 2
8    8 5 2 8 6 8
6    8 5 2 8 6 6

然而,当使用单行输入时失败,即

q)x:`a`b`c`d`e!5?10
q)fn[`time`data`id!(x`b;(x`a`b`c`d`e);x`a)]

time data id
------------
8    7    7
8    8    7
8    4    7
8    4    7
8    6    7

这显然是不正确的。 人们可能会通过使用 enlist 来解决这个问题,即

q)x:enlist `a`b`c`d`e!5?10
q)fn[`time`data`id!(x`b;(x`a`b`c`d`e);x`a)]

time| 8
data| 7 8 4 4 6
id  | 7

这是正确的,但是如果在函数中应用它,即

fn:{
   flip enlist `time`data`id!(x`b;(x`a`b`c`d`e);x`a)
 };

...

 time| 2 5 8 7 9
    data| 2 5 8 7 9 2 5 8 7 9 2 5 8 7 9 2 5 8 7 9 2 5 8 7 9
    id  | 2 5 8 7 9

数据值格式错误。 我的问题是如何避免这个转换问题并导出相同的字段值,无论参数是多行还是单行 table。 或者在 kdb+/q 中这个的规范实现是什么 谢谢

编辑: 澄清一下:我的问题不一定与数据输入有关,因为如果只有一行,则可以申请入伍。我的问题涉及如何在 fn 函数中使用 enlist 使单行输入符合使用多行 tables 时看到的逻辑。即如何用 fn 数据替换 fn enlist input(如何使函数输入不可知)谢谢

您的意思是翻转数据与 table 的其余部分垂直吗?您的 5 行示例有效,因为有 5 行和 5 列。由于 1 行到 5 列,单行不起作用。

如果我错了请纠正我,但我认为这就是你想要的:

fn:{([]time:x`b;data:flip x`a`b`c`d`e;id:x`a)};
--------------------------------------------------
t1:flip `a`b`c`d`e!(5#enlist til 5);
a b c d e
---------
0 0 0 0 0
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4

fn[t1]
time data      id
-----------------
0    0 0 0 0 0 0
1    1 1 1 1 1 1
2    2 2 2 2 2 2
3    3 3 3 3 3 3
4    4 4 4 4 4 4
--------------------------------------------------
t2:enlist `a`b`c`d`e!til 5;

a b c d e
---------
0 1 2 3 4

fn[t2]
time data      id
-----------------
1    0 1 2 3 4 0

注意没有翻转你得到这个:

([]time:t1`b;data:t1`a`b`c`d`e;id:t1`a)

time data      id
-----------------
0    0 1 2 3 4 0
1    0 1 2 3 4 1
2    0 1 2 3 4 2
3    0 1 2 3 4 3
4    0 1 2 3 4 4

在这种情况下,时间不再与数据一致,但由于有 5 行和列,所以可以正常工作。

编辑 - 除了在条件中首先使用 count 之外,我想不出更好的方法在需要时将字典转换为 table。请注意,如果第一个键是嵌套列表,这将不起作用

{ $[1 = count first x;enlist x;x] } `a`b`c`d`e!til 5

请注意,您提供的函数不适用于此:

{
   flip `time`data`id!(x`b;(x`a`b`c`d`e);x`a)
 }{$[1 = count first x;enlist x;x]} `a`b`c`d`e!til 5