我正在尝试创建一个clojure函数,该函数返回今天更改的目录中的文件。 它的功能部分=>给我今天更改的所有文件,遍历文件并查找特定值。列出文件和带有值的行。
我得到了解析部分+列出行/文件以及“更改过的文件”,但是我很难合并这两个文件。
到目前为止我设计的用于查找已更改文件的函数是:
(defn returnfilelist
"returns all the files changed today in a directory"
[d]
(def dir (io/file d))
(def files (for [file (file-seq dir) :when (= (datetostr (Date.(.lastModified file))) (datetostr (new Date))) ](str file )))
(doseq [f files] (println f) )) ;; <==== this indeed shows the files changed today...
我创建了datetostr函数来进行日期的实际比较:
(defn datetostr [date]
(str (.format (java.text.SimpleDateFormat. "yyyyMMdd")(.getTime date))))
此功能确实列出了今天更改的所有文件。 我现在想做的是通过“文件”#39;进入类似的功能:
(defn readdir [d]
(ff/returnfilelist d)) ;; more to add...
进一步处理。
我很欣赏这方面的一些帮助,我可能会监督一些简单的事情但它现在让我烦恼了几个小时。我一直在搜索文件和互联网上,但我没有找到正确的搜索表达式来获得答案。
方向已经足够,我喜欢学习,而且我对编程clojure还不错。
答案 0 :(得分:1)
一些事情:
def
。 def
定义并绑定包的全局命名空间中的符号,这几乎不是您想要做的。使用let
代替函数本地符号绑定。以下是返回文件列表,其中包含相应的更改(我已将其保持尽可能接近原始实现,以说明使代码正常工作的关键更改:使用filter
的其他答案更为惯用,并且应该是首选的):
(defn returnfilelist
"returns all the files changed today in a directory"
[d]
(let [dir (io/file d)
files (for [file (file-seq dir)
:when (= (datetostr (Date.(.lastModified file)))
(datetostr (new Date)))]
(str file))]
(doseq [f files] (println f)) ;; leaving this in for debugging
files)) ;; <--- the actual return value
...和readdir成为:
(defn readdir [d]
(let [todays-files (ff/returnfilelist d)]
;; more to add...
))
答案 1 :(得分:0)
要从函数返回一个值,必须由最后执行的语句生成。在您的情况下,您不会返回任何内容,而是在全局范围内定义新值(这本身就是不好的做法);您应该使用let
作为本地值:
(defn files-modified-today
[path]
(let [dir (io/file dir)]
(filter modified-today? (file-seq dir))))
(根据自己的喜好实施modified-today?
,例如您使用datetostr
在问题中所做的那样。)
由于for
形式是函数中执行的最后一个语句,因此它的结果将用作函数的返回值,可以在其他地方使用:
(defn read-dir
[path]
(for [f (files-modified-today path)]
(let [result (parse-file f)]
[f result]))))
这将返回一对seq,包含匹配的文件作为第一个元素,结果parse-file
(无论可能是什么)作为第二个。
我希望我没有完全错过你的问题。
答案 2 :(得分:0)
你的问题有点模糊。而且,你写的代码似乎远非惯用。我已经重写了下面的一些函数,向您介绍一些常见的clojure习语。
(import 'java.util.Date)
(defn date->str [date]
(-> (java.text.SimpleDateFormat. "yyyyMMdd") ;thread-first macro
(.format (.getTime date))
str))
(defn todays-files [dir]
"returns all the files changed today in a directory"
(let [today (new Date)] ;let bindings
(->> (file-seq (clojure.java.io/file dir)) ;thread-last macro.
(filter #(= (date->str (Date. (.lastModified %))) (date->str today)))
(map str))))
线程宏(线程优先和线程最后)用于创建执行单个数据转换的管道,然后传递给下一步。
应该使用绑定代替函数内的defs。
函数名称应该包含空格通常所在的破折号。使用 - &gt;也很常见。用于转换功能。例如,date-to-str变为date-&gt; str。
答案 3 :(得分:0)
一个宏,用于以递归方式或仅在父目录中列出目录中的文件。它还可以搜索带有特定结尾扩展名的文件。
;; lists all the files recursively inside the directory passed as d like "."
(defmacro my-rec-list
"generate the recursive list" {:added "1.0"}
[d str rec]
`(->> ~d
clojure.java.io/file
~(if (= rec "rec")
`file-seq
`(.listFiles))
~(cond
(= str "file") `(filter #(.isFile %))
(= str "dir") `(filter #(.isDirectory %))
:always `(filter #(.matches (.getPathMatcher
(java.nio.file.FileSystems/getDefault)
~str) (.getFileName (.toPath %)))))
(mapv #(.getAbsolutePath %))))
(defn my-rec-ls-file
"generate the recursive list for only files in a directory"
[d ]
(my-rec-list d "file" "rec"))
(defn my-rec-ls-dir
"generate the recursive list for only directory"
[d ]
(my-rec-list d "dir" "rec"))
(defn my-rec-ls-jpg
"generate the recursive list for files and directory"
[d ]
(my-rec-list d "glob:*.jpg" "rec"))
(defn my-ls-file
"generate the recursive list for only files in a directory"
[d ]
(my-rec-list d "file" "norec"))
(defn my-ls-dir
"generate the recursive list for only directory"
[d ]
(my-rec-list d "dir" "norec"))
(defn my-ls-jpg
"generate the recursive list for files and directory"
[d ]
(my-rec-list d "glob:*.jpg" "norec"))
它导致不同的功能,可以通过目录调用该函数以递归或非递归的方式获取文件列表,目录或匹配的扩展文件。例子是-
(def directory (clojure.java.io/file "/Path/to/Directory"))
(my-rec-ls-jpg directory) ;; find all jpg file recessively in directory
(my-ls-jpg directory) ;; find jpg file in current directory