4
我想建立一个功能,其中,由于一个二维矩阵,并从该矩阵的一些元素,将返回元素的位置的指标:评估参数宏观
(get-indices [[1 2 3] [4 5 6] [7 8 9]] 6)
;=> [1 2]
其中,由于回获得式,将返回元素本身:
(get-in [[1 2 3] [4 5 6] [7 8 9]] [1 2])
;=> 6
我想要的功能(GET-指数)要快,所以我想这样做宏将扩展到类似的(cond ...)
部分东西此功能(但是对于每个尺寸为NxN的2D矩阵都是通用的):
(defn get-indices
[matrix el]
(let [[[a b c] [d e f] [g h i]] matrix]
(cond
(= a el) [0 0]
(= b el) [0 1]
(= c el) [0 2]
(= d el) [1 0]
(= e el) [1 1]
(= f el) [1 2]
(= g el) [2 0]
(= h el) [2 1]
(= i el) [2 2])))
我想出了这个宏:
(defmacro get-indices
[matrix el]
(let [size (count matrix)
flat (flatten matrix)
compare-parts (map #(list '= % el) flat)
indices (for [x (range size) y (range size)] [x y])]
(cons 'cond (interleave compare-parts indices))))
似乎刚刚好......但是,当使用var调用,而不是直接的价值,它抛出一个异常:
(def my-matrix [[1 2 3] [4 5 6] [7 8 9]])
(get-indices my-matrix 6)
;=> java.lang.UnsupportedOperationException: count not supported on this
; type: Symbol (NO_SOURCE_FILE:0)
对我来说,似乎符号“矩阵”不解决宏值扩展时间或类似的东西,但我绝对是宏的初学者...
我怎样才能让这个宏也与变量一起工作呢?
我也在考虑使用语法引用等,但我想避免让(let ...)
作为宏输出的一部分,也不知道如何在语法引用中实现(interleave compare-parts indices)
...
请注意,您可以使用重复的“调入”调用来更轻松地编写此代码 - 我选择一次遍历矩阵中的一行和一个元素,以避免随机访问和(希望提高)性能,因为您似乎关心。 – amalloy 2012-03-08 22:12:08
感谢您的澄清和功能!它真的很快(虽然看起来不比想要写的更快 - 而且不可能写出来 - 宏;-)。只有一个问题:你的意思是什么随机访问? – mnicky 2012-03-09 10:54:23
哦,也许我已经看到你的意思了:在增加索引时调用'get-in',从而随机访问矩阵,不是吗? – mnicky 2012-03-09 11:13:18