... Возможно, обязательное программирование с изменчивыми данными просто слишком глубоко пробурено в моем мозгу, но я нахожу код для создания векторов данных в 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?)
guard и т.д. И т.д. Все это так повторяется, что заставляет меня кричать.
В простых случаях map
будет достаточно, но я думаю о случаях, когда есть несколько уровней вложенности, и на каждом уровне могут быть условия, требующие пропустить итерацию.
В Common Lisp я могу использовать макрос loop
или mapcan
. Не имеет ли Clojure что-либо вроде mapcan
?