clojure函数返回目录中的文件
我正在尝试创建一个clojure函数,该函数返回今天更改的目录中的文件。 这是功能的一部分=>给我今天更改的所有文件,循环浏览文件并查找特定值。列出文件和带有该值的行 我得到了解析部分+列出行/文件以及“更改的文件”,但是我很难将两者合并 到目前为止,我设计的查找已更改文件的功能是:clojure函数返回目录中的文件,clojure,Clojure,我正在尝试创建一个clojure函数,该函数返回今天更改的目录中的文件。 这是功能的一部分=>给我今天更改的所有文件,循环浏览文件并查找特定值。列出文件和带有该值的行 我得到了解析部分+列出行/文件以及“更改的文件”,但是我很难将两者合并 到目前为止,我设计的查找已更改文件的功能是: (defn returnfilelist "returns all the files changed today in a directory" [d] (def dir (io/file d)) (def
(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...
此函数确实列出了今天更改的所有文件。
我现在想做的是将“文件”传递到如下函数:
(defn readdir [d]
(ff/returnfilelist d)) ;; more to add...
以便进一步处理
我很感谢在这方面的帮助,我可能正在监督一些简单的事情,但它让我现在窃听了几个小时。我一直在clojure文档和互联网上搜索,但我没有找到正确的搜索表达式来获得答案
方向就足够了,我喜欢学习,而且我对clojure编程相当陌生。要从函数返回值,它必须由函数中执行的最后一条语句生成。在您的情况下,您没有返回任何内容,而是在全局范围内定义新的值(这本身就是一种糟糕的做法);对于局部值,应使用
let
:
(defn files-modified-today
[path]
(let [dir (io/file dir)]
(filter modified-today? (file-seq dir))))
(根据您的喜好实施今天修改?
,例如,就像您在问题中使用datetostr
所做的那样)
由于表单的是函数中执行的最后一条语句,因此其结果将用作函数的返回值,并可从其他地方使用:
(defn read-dir
[path]
(for [f (files-modified-today path)]
(let [result (parse-file f)]
[f result]))))
这将返回一系列对,其中包含匹配的文件作为第一个元素,以及解析文件的结果作为第二个元素
我希望我没有完全错过你的问题。你的问题有点模糊。此外,您正在编写的代码似乎还远远不是惯用的。我重写了下面的一些函数,向您介绍一些常见的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))))
线程宏(thread first和thread last)用于创建执行单个数据转换的管道,然后传递到下一步
函数中应该使用let绑定而不是defs
函数名应该在空格通常所在的位置使用破折号。对转换函数使用->也是很常见的。例如,date to str变成date->str.两件事:
returnfilelist在函数内部使用def
def
在包的全局命名空间中定义和绑定符号,这几乎不是您想要做的。使用let
代替函数本地符号绑定
returnfilelist从未实际返回它计算的内容。函数中涉及doseq的最后一条语句实际上返回nil。您可能希望返回文件
下面是带有适当更改的returnfilelist(我已尽可能地将其与原始实现保持接近,以说明使代码正常工作的关键更改:使用过滤器的其他答案更为惯用,应该是首选):
一个宏负责列出目录中的文件-递归地或仅在父目录中。它还可以搜索具有特定结尾扩展名的文件
;; 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"))
它导致了不同的函数,可以使用directory调用这些函数,以递归或非递归方式获取文件列表、目录或匹配的扩展文件。例如-
(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
感谢约塞米蒂马克的回复。我不知道如何返回值并使用它。既然你们三个对let、filter和idiom都发表了相同的评论,我需要对此进行更多的研究。我将首先了解您的代码,以便了解代码中的错误,然后我将了解其他两个,以进一步了解clojure语言结构。
(defn readdir [d]
(let [todays-files (ff/returnfilelist d)]
;; more to add...
))
;; 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