2017-05-05 35 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 ...)'之前的一種老技術,現在被認爲已經過時了。 –