2017-05-05 32 views
1

我似乎有一个困难的理解我应该如何使用clojure map。我有一个名为in-grids的对象列表,我不想使用方法getCoordinateSystem。我想列表中的对象是一些Java类是很重要的。当我在clojure中直接定义函数时,map起作用。clojure不能通过地图应用功能列表

这工作:

(.getCoordinateSystem (first in-grids))

但不是这个

(map .getCoordinateSystem in-grids)

和错误是:java.lang.RuntimeException: Unable to resolve symbol: .getCoordinateSystem in this context

我可能失去了一些东西真的很明显这里,但什么究竟?

回答

5

如果你有形式

(map f sequence) 

然后f应参照IFn一个实例,然后调用为sequence每个元素的表达。

.是一种特殊形式,并且.getCoordinateSystem没有引用IFn实例。

(.getCoordinateSystem (first in-grids)) 

相当于

(. (first in-grids) (getCoordinateSystem)) 

可以构造一个函数值例如直接

(map #(.getCoordinateSystem %) in-grids) 
+0

完美的,我用了'#(%)'建造之前,但在这里忘了! – kakk11

2

这往往是map一个方便的替代方案是for函数的另一选择:

(for [grid in-grids] 
    (.getCoordinateSystem grid)) 

以这种方式使用for具有如map相同的效果,但是在“一个更明确的一点一次处理“的性质。另外,由于您直接调用Java函数getCoordinateSystem,因此不需要将其封装在Clojure函数文字中。

+0

谢谢,您的解决方案很好理解。 – kakk11

0

作为Lee答案的替代方法,有memfn宏,它扩展为与该答案类似的代码。

(map (memfn getCoordinateSystem) in-grids) 

(macroexpand '(memfn getCoordinateSystem)) 
;=> (fn* ([target56622] (. target56622 (getCoordinateSystem)))) 
+0

'memfn'是函数文字'#(my-fn ...)'之前的一种老技术,现在被认为已经过时了。 –