Clojure for
宏正與任意Clojure序列一起使用。
這些序列可能會或可能不會像向量一樣暴露隨機訪問。因此,在一般情況下,如果沒有遍歷所有Clojure序列的最後一個元素,您將無法訪問它的最後一個元素,從而無法通過相反的順序來遍歷它。
我assumming你腦子裏想的是這樣的(類似Java的僞代碼):
for(int i = n-1; i--; i<=0){
doSomething(array[i]);
}
在這個例子中,我們事先知道數組大小n
,我們可以通過它的索引訪問元素。用Clojure序列我們不知道。在Java中,使用數組和ArrayLists來做到這一點是有意義的。然而,Clojure序列更像鏈接列表 - 你有一個元素,並引用下一個。
順便說一句,即使有一個
(可能非慣用語)
*的方式來做到這一點,其時間複雜度會像爲O(n^2)相比,更容易的解決方案,是不值得的努力在鏈接的文章中,列表的O(n^2)和矢量的O(n)好得多(而且它非常優雅和習慣,事實上,官方的reverse
也有這個實現)。
編輯:
一般的建議是:不要試圖做Clojure的命令式編程,它不適合它。儘管許多事情看起來很奇怪或者反直覺(與衆所周知的命令式編程中的習慣用法相反),但是一旦習慣了功能性的處理方式,它很多,我的意思是很容易。
特別爲這個問題,儘管同名Java(和其他類C)for
和Clojure for
是不一樣的東西!首先是一個實際的循環 - 它定義了一個流量控制。第二個是一個理解 - 看它在概念上作爲一個序列的更高功能和功能˚F做每個其元件,它返回F(元件) S的另一序列的。 Java for
是一個聲明,它不計算任何東西,Clojure for
(以及Clojure中的其他任何東西)是一個表達式 - 它評估的是序列f(element) s。
可能最簡單的方法是使用序列函數庫:http://clojure.org/sequences。此外,您可以在http://www.4clojure.com/上解決一些問題。第一個問題非常簡單,但隨着你逐步完成,它們會逐漸變得更加困難。
*如亞歷山大的回答所示,問題的解決方案實際上是慣用的,而且非常聰明。榮譽! :)
這是我一直在尋找的東西。無突變獎金。謝謝。 – noahlz
如果String支持'rseq',那麼這樣可以很好,這樣你就可以做到這一點,而不需要爲了反轉而遍歷字符串的開銷。 – amalloy
@amalloy是的。當我寫這個答案時,我發現你的郵件列表發佈了這個問題,並且爲* clojure字符串rseq *搜索了谷歌。儘管如此,顛倒一個字符串並不是你必須這麼做的。 –