1

我需要类似 Mathematica 的 Position 函数(http://reference.wolfram.com/mathematica/ref/Position.html),但在 Q 中。我的矩形矩阵解决方案如下:

q) colrow:{sz:count x; $[(count first x) = 1; enlist y; (floor y % sz;  y mod sz)]}
q) position:{flip colrow[x;(where raze x = y)]}

它适用于矩形矩阵和列表:

q) t:(1 -1  1;  / matrix test
     -1  3  4; 
      1 -1  1);

q) pos1:position[t;-1]   / try to find all positions of -1
q) pos1
 0 1
 1 0
 2 1

q) t ./: pos1   / here get items
 -1 -1 -1

q) l:1 0 3 0 2 3 4 1 0  / list test
q) pos2:position[l;0]   / try to find all positions of 0

q) pos2
 1
 3
 8

q) l ./: pos2 / get items
 0 0 0 

这可行,但最好为任意列表提供更通用的解决方案,而不仅仅是矩形矩阵。例如,上面的代码对于以下参数将无法正常工作:

position[(1 2 3; 1 2; 1 2 1 4); 1]

可能有人对此有通用解决方案吗?

4

2 回答 2

3

这个样子怎么样?我认为它应该适用于所有二维列表,不规则或矩形,也适用于向量。(我还没有制定出任意尺寸的版本。)

q)position:{{$[type x;enlist each where x;raze flip each flip(til count x;raze each .z.s each x)]}x=y}
q)t
1  -1 1
-1 3  4
1  -1 1
q)l
1 0 3 0 2 3 4 1 0
q)r
1 2 3
1 2
1 2 1 4
q)pos1:position[t;-1]
q)pos2:position[l;0]
q)pos3:position[r;1]
q)pos1
0 1
1 0
2 1
q)pos2
1
3
8
q)pos3
0 0
1 0
2 0
2 2
q)t ./:pos1
-1 -1 -1
q)l ./:pos2
0 0 0
q)r ./:pos3
1 1 1 1
q)

编辑:

这是一个适用于除1(当然还有 0)之外的所有维度的版本:

q)position2:{{$[type x;where x;raze each raze flip each flip(til count x;.z.s each x)]}x=y}
q)r2:(r;r)
q)0N!r2;
((1 2 3;1 2;1 2 1 4);(1 2 3;1 2;1 2 1 4))
q)pos4:position2[r2;1]
q)0N!pos4;
(0 0 0;0 1 0;0 2 0;0 2 2;1 0 0;1 1 0;1 2 0;1 2 2)
q)r2 ./:pos4
1 1 1 1 1 1 1 1
q)r ./:position2[r;1]
1 1 1 1
q)t ./:position2[t;-1]
-1 -1 -1
q)

但是,在向量上,它返回一个地址向量,而不是地址矩阵,因此它必须与 一起使用@,而不是.

q)0N!position2[l;0];
1 3 8
q)l ./:position2[l;0]
'type
q)l position2[l;0]
0 0 0
q)

如果你真的需要它在向量上以与在高维结构上相同的方式工作,最简单的解决方案可能只是直接对它们进行特殊处理:

q)position3:{$[type x;enlist each where@;{$[type x;where x;raze each raze flip each flip(til count x;.z.s each x)]}]x=y}
q)position3[l;0]
1
3
8
q)l ./:position3[l;0]
0 0 0
q)r2 ./:position3[r2;1]
1 1 1 1 1 1 1 1
q)r ./:position3[r;1]
1 1 1 1
q)t ./:position3[t;-1]
-1 -1 -1
q)
于 2014-05-07T15:48:19.880 回答
0

下面也应该工作。
不是确切的解决方案,但可行。

pos:{$[type x;where x=y;where each x=y]}  
val:{raze ($[0h=type x;x@';x@])pos[x;y]}  
q)t:(1 -1  1;-1 3 4;1 -1 1)  
q)pos[t;-1]  
1  
0  
1  
q)val[t;-1]  
-1  
-1  
-1  
q)l:1 0 3 0 2 3 4 1 0  
q)pos[l;0]  
1 3 8  
q)val[l;0]  
0 0 0  
q)r:(1 2 3; 1 2; 1 2 1 4)  
q)pos[r;1]  
,0
,0
0 2
q)val[r;1]  
1 1 1 1  
于 2014-05-08T19:34:39.450 回答