我有一个建立列表的递归函数:
(defn- traverse-dir
"Traverses the (source) directory, preorder"
[src-dir dst-root dst-step ffc!]
(let [{:keys [options]} *parsed-args*
uname (:unified-name options)
[dirs files] (list-dir-groomed (fs/list-dir src-dir))
... traverse-dir 的递归调用是 dir-handler
的最后一个表达式 (doall (concat (map-indexed (dir-handler) dirs) (map-indexed (file-handler) files))))) ;; traverse-dir
由 traverse-dir 构建的列表是递归的,而我想要一个扁平的列表:
flat-list (->> (flatten recursive-list) (partition 2) (map vec))
首先是否有建立单位清单的方法?没有使用可变列表,即。
答案 0 :(得分:1)
我不太了解你的上下文,dir-handler
没有任何东西,并且返回一个函数,它需要索引和目录,list-dir-groomed
以及所有这些,但我' d建议查看tree-seq
:
(defn tree-seq
"Returns a lazy sequence of the nodes in a tree, via a depth-first walk.
branch? must be a fn of one arg that returns true if passed a node
that can have children (but may not). children must be a fn of one
arg that returns a sequence of the children. Will only be called on
nodes for which branch? returns true. Root is the root node of the
tree."
{:added "1.0"
:static true}
[branch? children root]
(let [walk (fn walk [node]
(lazy-seq
(cons node
(when (branch? node)
(mapcat walk (children node))))))]
(walk root)))
我在这里使用的是
(tree-seq #(.isDirectory %) #(.listFiles %) (clojure.java.io/as-file file-name))
但你的背景可能意味着不起作用。如果需要清理子文件,可以更改为获取子文件的不同函数,或者只需在输出中使用filter
即可。如果这没有好处,那么从节点进入预处理的本地fn的相同模式通过递归地映射自己来处理子节点似乎是非常适用的。