Clojure创建目录层次结构 - 但不是以程序方式

Mar*_*tus 7 clojure

假设我需要在Clojure中创建以下目录结构:

a
\--b
|   \--b1
|   \--b2
\--c
   \-c1
Run Code Online (Sandbox Code Playgroud)

而不是做如下的程序性事情:

(def a (File. "a"))
(.mkdir a)
(def b (File. a "b"))
(.mkdir b)
;; ...
Run Code Online (Sandbox Code Playgroud)

...是否有一种聪明的方式以某种方式将上述操作表示为数据,以声明方式,然后一举创建层次结构?

Art*_*ldt 8

一个快速而简单的方法是创建一个dirs矢量来创建mkdir并将其映射到它:

user> (map #(.mkdir (java.io.File. %)) ["a", "a/b" "a/b/c"])
(true true true)
Run Code Online (Sandbox Code Playgroud)

或者你可以将你的目录结构指定为一棵树,并使用拉链来走路,让路上的dirs:

(def dirs ["a" ["b" ["b1" "b2"]] ["c" ["c1"]]])
(defn make-dir-tree [original]
  (loop [loc (zip/vector-zip original)]
    (if (zip/end? loc)
      (zip/root loc)
      (recur (zip/next
              (do (if (not (vector? (zip/node loc)))
                    (let [path (apply str (interpose "/" (butlast (map first (zip/path loc)))))
                          name (zip/node loc)]
                      (if (empty? path)
                        (.mkdir (java.io.File. name))
                        (.mkdir (java.io.File. (str path "/" name))))))
                  loc))))))
(make-dir-tree dirs)
Run Code Online (Sandbox Code Playgroud)

.

arthur@a:~/hello$ find a
a
a/c
a/c/c1
a/b
a/b/c
a/b/b2
a/b/b1
Run Code Online (Sandbox Code Playgroud)

如果您正在进行大量的一般系统管理,那么可能需要更重的东西.该托盘项目是做物理和云托管系统的各种系统管理(虽然它往往对混浊的东西瘦)的库.特别是目录

  • 我建议提一下`map`可能出现的问题. (2认同)
  • 会做!,总是留意懒虫 (2认同)
  • 您可以使用`doseq`而不是`map`来避免懒惰,因为您不关心每个`mkdir`的结果. (2认同)