将文件列在Clojure中的两个单独目录中

时间:2017-10-19 23:09:19

标签: clojure

我试图让Overtone在我的Windows 10机器上运行。我似乎在代码中发现了一个试图启动合成器服务器的错误。 Overtone依赖于SuperCollider,它通过查看SuperCollider的安装位置来查找scsynth.exe的位置。但是应该检查C:\Program FilesC:\Program Files (x86)的代码只检查存在的第一个而不是两个:

(import java.io File)
(let [p-files-dir (System/getenv "PROGRAMFILES(X86)")
      p-files-dir (or p-files-dir (System/getenv "PROGRAMFILES"))
      p-files-dir (File. p-files-dir)
      p-files     (map str (.listFiles p-files-dir))
      p-files])

在我的情况下,两个目录都存在,但SuperCollider仅存在于C:\Program Files中。上面的代码段仅列出C:\Program Files (x86)中的文件。

如何让这段代码返回两个目录中的所有文件,而不是在一个目录不存在时中断?

1 个答案:

答案 0 :(得分:4)

您没有从let表单中返回任何内容,因此请注意此处p-files位于[]之外:

(let [p-files-dir-1 (System/getenv "PROGRAMFILES(X86)")
      p-files-dir-2 (System/getenv "PROGRAMFILES")
      p-files-dir-file-1 (File. p-files-dir-1)
      p-files-dir-file-2 (File. p-files-dir-2)
      p-files (map str (concat 
                         (.listFiles p-files-dir-file-1) 
                         (.listFiles p-files-dir-file-2)))]
  p-files)

您的问题的答案是,您可以concat将两个列表放在一起,之后您需要过滤该文件。

这里的答案较短(此处map str并非严格必要):

(map str (concat ["a" "b" "c"] ["d" "e" "f"]))
;; => ("a" "b" "c" "d" "e" "f")

要删除所有临时变量,您可以使用此功能:

(defn env-files [file-name]
  (some-> file-name
          System/getenv
          File.
          .listFiles))

然后代码变为:

(map str (concat
             (env-files "PROGRAMFILES(X86)")
             (env-files "PROGRAMFILES")))