Clojure 每次从序列中获取两个元素
clojure是否有像common lisp那样强大的“循环” 例如: 每次从序列中获取两个元素 公共Lisp:Clojure 每次从序列中获取两个元素,clojure,Clojure,clojure是否有像common lisp那样强大的“循环” 例如: 每次从序列中获取两个元素 公共Lisp: (loop for (a b) on '(1 2 3 4) by #'cddr collect (cons a b)) 如何在Clojure中实现这一点?有,这是一个类似于工作循环的循环,还有和,它们都基于for Common Lisp。通过利用for和一些解构,您可以实现特定的示例: (for [[a b] (partition 2 [1 2 3 4])](use-a-and-b
(loop for (a b) on '(1 2 3 4) by #'cddr collect (cons a b))
如何在Clojure中实现这一点?有,这是一个类似于工作循环的循环,还有和,它们都基于for Common Lisp。通过利用
for
和一些解构,您可以实现特定的示例:
(for [[a b] (partition 2 [1 2 3 4])](use-a-and-b a b))
Clojure的多用途循环结构是
for
。它没有CL内置的循环
那么多功能(特别是没有副作用的功能,因为Clojure鼓励功能的纯洁性),因此您可能只需使用循环
本身就可以完成的许多操作都是为而“围绕”完成的。例如,要对为
生成的元素求和,您需要在其前面放置一个apply+
;要成对地遍历元素,您可以(如sw1nn所示)对输入到for
的输入序列使用分区2
,循环
,递归
和解构
例如,如果我想将每两个值分组在一起:
(loop [[a b & rest] [1 2 3 4 5 6]
result []]
(if (empty? rest)
(conj result [a b])
(recur rest (conj result [a b]))))
结果是:
=>[[1 2][3 4][5 6]]
a
和b
分别是序列的第一个和第二个元素,剩下的是rest
。然后我们可以反复循环,直到rest
中没有剩余的内容,我们就完成了。请注意for
不是循环构造,而是列表理解,产生了一个惰性的结果序列。另外,与普通的LISP相比,很难让它表现得非常好。@Marko-你有具体的例子吗?不明白-具体的例子是什么?我的观点不是具体的,而是一般性的。Lisp的loop
是一种执行控制结构,更类似于Clojure中的doseq
或loop
。OP的示例专门使用collect
来指定类似map
的操作,这只是使用loop
的一种方法。在Clojure中,通常用于for
的东西,如惰性seq、高阶函数、分区产生的辅助向量等,在时间和空间上都很昂贵。@St3fan-谢谢-我的评论应该是“性能差的例子”。如果没有特定的用例,挥手“表现很差”或“很难让它表现得非常好”是没有用的。性能并不总是最重要的考虑因素,clojure在许多地方用清洁和简单换取原始性能。“问题”在于,性能很容易量化,而清洁度/简单性则不然,因此评估权衡可能很困难。我喜欢简单而不是效率,效率而不是性能,除非我真的知道我有问题。。。