Clojure 每次从序列中获取两个元素

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

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 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在许多地方用清洁和简单换取原始性能。“问题”在于,性能很容易量化,而清洁度/简单性则不然,因此评估权衡可能很困难。我喜欢简单而不是效率,效率而不是性能,除非我真的知道我有问题。。。