我正在学习clojure,并且我编写了一个小函数,给定一个目录路径名根据它们的mtimes以降序返回文件的排序映射。这是:
(defn get-sorted-mtimes [dir]
(loop [sm (sorted-map-by >)
lst (for [f (.listFiles (File. dir))]
(let [k (.lastModified f)
v (.getName f)]
[k v]))]
(if (seq lst)
(recur (assoc sm ((first lst) 0) ((first lst) 1))
(rest lst))
sm)))
我的问题是:有没有办法将比较器方法作为符号名称传递给函数并使其按相应的asc或desc顺序排序?我的意思是:
(defn get-sorted-mtimes [dir <sym>]
(loop [sm (sorted-map-by <sym>)
...
此外,还有更多的clojuresque方式来完成这项任务吗?
嗯,为了记录,这是函数的最终形式,完全符合我的需要:
(defn get-sorted-mtimes [dir comp]
(loop [sm (sorted-map-by (comparator comp))
lst (for [f (.listFiles (File. dir))]
(let [k (.lastModified f)
v (.getName f)]
[k v]))]
(if (seq lst)
(recur (assoc sm ((first lst) 0) ((first lst) 1))
(rest lst))
sm)))
如果未使用(比较器)函数,则会出现java.lang.ClassCastException异常。
答案 0 :(得分:4)
>
就像Clojure中的任何其他功能一样。所以没有什么可以阻止你把它作为一个论点。
事实上,我认为这样做是很好的Clojure风格。 Clojure本质上是一种函数式编程语言,所以在适当的地方使用higher order functions并没有错!
其他一些小建议:
comparator
代替<sym>
作为函数参数的名称。我认为这更具描述性,并且与Clojure的常规命名约定更加一致。get-mtime
这样的函数(一个返回文件mtime的简单函数)。 (into sm lst)
- 比你的大循环/ if / recur构造简单得多!然后你可以做一些非常好的事情,比如(get-sorted-files (list-files-recursive dir) > get-mtime)
- 或者你能想到的任何类似的组合!