球拍 - 最简洁的列表理解方式?

时间:2014-01-16 04:24:42

标签: scheme racket

我有一些代码可以在当前目录中找到最近修改过的某种类型的文件(见下文)。我的问题是:是否有更简洁,也许更惯用的Racket,表达此代码的方式?这个想法很简单:在目录中获取某种类型的所有文件,然后只选择最近修改过的文件。我使用cwd-paths-of-type尝试了for*/list的变体,但它似乎不太可读。我觉得我错过了什么。谁能开导我?

#lang racket

(define FILETYPE ".pdf")

(define (cwd-paths-of-type filetype)
  (filter
    (lambda (p)
      (define filename (path->string p))
      (and
        (>= (string-length filename) 4)
        (string=?
          (substring filename (- (string-length filename) 4))
          filetype)))
    (directory-list)))

(define (last-mod-path paths)
  (define last-mod-time
    (apply
      max
      (map file-or-directory-modify-seconds paths)))
  (first
    (filter
      (lambda (p)
        (equal?
          (file-or-directory-modify-seconds p)
          last-mod-time))
      paths)))

(displayln
  (last-mod-path (cwd-paths-of-type FILETYPE)))

2 个答案:

答案 0 :(得分:7)

几个球拍功能可以在这里为您提供帮助,filename-extensionargmax

请注意filename-extension的结果是byte string,但如果必须使用字符串,则很容易转换。

(define FILETYPE #"pdf")

(define (cwd-paths-of-type filetype)
  (filter
   (λ (p) 
     (define ext (filename-extension p))
     (and ext (bytes=? ext filetype)))
   (directory-list)))

(define (last-mod-path paths) (argmax file-or-directory-modify-seconds paths))

(displayln (last-mod-path (cwd-paths-of-type FILETYPE)))

答案 1 :(得分:0)

这是编写last-mod-path的另一种方法,不使用map和filter and apply,而是使用迭代方法。无需两次使用这些功能,即。

(define (last-mod-path paths)
  (if (null? (cdr paths)) (car paths)
    (if (> (file-or-directory-modify-seconds (car paths)) 
           (file-or-directory-modify-seconds (last-mod-path (cdr paths))))
        (car paths)
        (last-mod-path (cdr paths)))))