...也许使用可变数据的命令式编程已经深入我的大脑,但我发现在 Clojure 中构建数据向量的代码冗长、笨拙且令人费解。肯定有更好的办法!
在 Ruby 中,我可能会编写如下代码:
results = []
a_collection.each do |x|
x.nested_collection.each do |y|
next if some_condition_holds
results << y
end
end
在 Clojure 中,我不知道有比使用递归函数更好的方法,也许像下面的(可怕的)代码:
; NEWBIE ALERT! NEWBIE ALERT!
(loop [results []
remaining a_collection]
(if (empty? remaining)
results
(recur
(loop [results results
nested (nested_collection (first remaining))]
(if (empty? nested)
results
(if (some_condition_holds)
(recur results (rest nested))
(recur (conj results (first nested)) (rest nested)))))
(rest remaining))))
如果没有可变数据和迭代循环,您需要使用递归来构建集合。每个这样的递归函数都需要一个(empty?)
保护子句,等等。整个事情是如此重复,让我想尖叫。
在简单的情况下,map
就足够了,但我正在考虑存在多个嵌套级别的情况,并且在每个级别上,可能存在需要跳过迭代的条件。
在 Common Lisp 中,我可能会使用loop
宏或mapcan
. Clojure没有类似的东西mapcan
吗?