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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.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-是否可以在doseq语句中增加变量?_Clojure - Fatal编程技术网

Clojure-是否可以在doseq语句中增加变量?

Clojure-是否可以在doseq语句中增加变量?,clojure,Clojure,我试图迭代给定目录中的文件列表,并在其名称中添加递增变量I={1,2,3..} 下面是我用来迭代文件并更改每个文件名的代码: (defn addCounterToExtIn [d] (def i 0) (doseq [f (.listFiles (file d)) ] ; make a sequence of all files in d (if (and (not (.isDirectory f)) ; if file is not a directry and

我试图迭代给定目录中的文件列表,并在其名称中添加递增变量I={1,2,3..}

下面是我用来迭代文件并更改每个文件名的代码:

(defn addCounterToExtIn [d]
  (def i 0)
  (doseq [f (.listFiles (file d)) ] ; make a sequence of all files in d
    (if (and (not (.isDirectory f)) ; if file is not a directry and
             (= '(\. \i \n) (take-last 3 (.getName f))) ) ; if it ends with .in
      (fs/rename f (str d '/ i (.getName f)))))) ; add i to start of its name

doseq
迭代每个文件时,我不知道如何增加
I
。或者,是否有更好的循环来实现期望的结果?

这是我头脑中的第一个方法。这并不理想,但肯定比问题所提出的更为地道

(def rename-one-file! [file counter]
  (if (and (not (.isDirectory file))
           (= ".in" (str (take-last 3 (.getName file)))))
      (fs/rename file (file (parent dir)
                            (str counter (.getName file)))))


(defn iterate-files-with-counter [fn dir]
  (loop [counter 0
         remaining-files (.listFiles (file dir))]
    (let [current-file (first remaining-files)]
      (fn file counter)
      (recur (+ counter 1) (rest remaining-files))))

(def add-counter-to-ext-in-dir
  (partial iterate-files-with-counter rename-one-file!))
请注意,实际执行重命名的工作与迭代文件的工作是分开的。一般来说,拥有大量的小功能比拥有少量的大功能要好,并且使这些功能可重用/独立,除非您选择将它们一起使用,否则比这更好。

使用和:

映射索引中的函数更改为重命名即可。
pdf文件的示例输出:

([0 #<File /home/eduard/Downloads/some.pdf>] ...)
([0#]…)

为什么要将变量的范围扩展到它所用于的操作之外?
def
创建一个顶级
var
,正如Charles Duffy指出的那样,它是一个顶级值,存在于函数运行之外,更重要的是,如果要进行变异,通常是错误的。此外,clojure中的惯用用法是完全消除突变的直接使用(如下面他的回答所示)。感谢您的解释您可能会发现这段代码很有用:注意,这都是即兴编写的,没有经过测试,所以它肯定不是完美的——但目标是展示惯用语/良好实践。在这种情况下,遵循惯用语是否真的很重要,或者我也可以使用变异,但你只是想向我展示同样的惯用方法?@YechielLabunskiy,使用vars进行变异会导致现实世界中的错误和性能问题。正确使用习惯用法并不总是很重要,但最初的代码有实际的错误(例如,想想如果同时从两个线程调用它会发生什么)。谢谢——当您发现这个问题时,我实际上正在寻找地图索引来修改我自己的答案。:)请注意,file seq是递归的,也将返回子目录中的文件。是否有方法使索引以0以外的值开始?@YechielLabunskiy您可以
(inc i)
在映射索引的函数内。我想你已经得到了这个答案:)
([0 #<File /home/eduard/Downloads/some.pdf>] ...)