Clojure-将文件路径转换为树

JFo*_*rth 0 tree clojure

我对Clojure还是陌生的,因此我在如何使用文件路径在Clojure中创建树感到很苦恼。我使用file-seq将所有文件保存在目录下,并将它们存储在中files。输入是一个文件路径,如下所示:

resources/data/2012/05/02/low.xml
resources/data/2012/05/01/low.xml
Run Code Online (Sandbox Code Playgroud)

我可以使用以下命令获取文件夹和文件的所有单独名称:

(for [x files] 
 (if (.contains (.getPath x) ".json")
  (for [y (str/split (.getPath x) #"\\")] y)))
Run Code Online (Sandbox Code Playgroud)

这给了我所有文件夹的列表,但是我不知道如何将它们组合成一个列表来创建树形结构。如果有任何答案可以解释他们的代码如何工作,以帮助学习。这2个输入的期望输出为:

(resources (data (2012 (05 (02 (low.xml)) (01 (low.xml))))))
Run Code Online (Sandbox Code Playgroud)

lee*_*ski 5

您需要建立树是这样的:

(defn as-tree [data]
  (map (fn [[k vs]] (cons k (as-tree (keep next vs))))
       (group-by first data)))
Run Code Online (Sandbox Code Playgroud)

给定已解析路径的列表(或一般而言,任何序列),它将创建您的结构:

user> (as-tree [["resources" "data" "2012" "05" "02" "low.xml"]
                ["resources" "data" "2012" "05" "01" "aaa.xml"]
                ["resources" "data" "2012" "05" "02" "high.xml"]
                ["resources" "data" "2012" "05" "01" "xsxs.xml"]
                ["resources" "data" "2012" "06" "01" "bbb.xml"]
                ["resources" "data" "2012" "05" "01" "ccc.xml"]
                ["resources" "data" "2012" "02" "some.xml"]
                ["resources" "data" "2012" "01" "some2.xml"]
                ["other-resources" "data" "2015" "10" "some100.xml"]])

;; (("resources" 
;;   ("data" 
;;     ("2012" 
;;       ("05" 
;;         ("02" ("low.xml") 
;;               ("high.xml")) 
;;         ("01" ("aaa.xml") 
;;               ("xsxs.xml") 
;;               ("ccc.xml"))) 
;;       ("06" 
;;         ("01" ("bbb.xml"))) 
;;       ("02" ("some.xml")) 
;;       ("01" ("some2.xml"))))) 
;;  ("other-resources" ("data" ("2015" ("10" ("some100.xml"))))))
Run Code Online (Sandbox Code Playgroud)

因此,在您的情况下,它看起来可能像这样(.clj项目中文件的树):

(require '[clojure.string :as cs])
(import 'java.io.File)

(->> (File. ".")
     file-seq
     (map #(.getPath %))
     (filter #(cs/ends-with? % ".clj"))
     (map #(cs/split % (re-pattern File/separator)))
     as-tree
     first)

;;=> ("." 
;;     ("src" 
;;       ("playground" 
;;         ("core.clj"))) 
;;     ("test" 
;;       ("playground" 
;;         ("core_test.clj"))) 
;;     ("project.clj"))
Run Code Online (Sandbox Code Playgroud)