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 *搜索了谷歌。尽管如此,颠倒一个字符串并不是你必须这么做的。 –