Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
clojure函数返回目录中的文件_Clojure - Fatal编程技术网

clojure函数返回目录中的文件

clojure函数返回目录中的文件,clojure,Clojure,我正在尝试创建一个clojure函数,该函数返回今天更改的目录中的文件。 这是功能的一部分=>给我今天更改的所有文件,循环浏览文件并查找特定值。列出文件和带有该值的行 我得到了解析部分+列出行/文件以及“更改的文件”,但是我很难将两者合并 到目前为止,我设计的查找已更改文件的功能是: (defn returnfilelist "returns all the files changed today in a directory" [d] (def dir (io/file d)) (def

我正在尝试创建一个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...
此函数确实列出了今天更改的所有文件。 我现在想做的是将“文件”传递到如下函数:

(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