tags:

views:

108

answers:

2

i am trying to traverse a given directory and create a list of files ending in .jpg.

(setq files (list ))

(defun jpg-list(directory)  
  (dolist (node (directory-files directory t ) )
      (if (file-directory-p node)      
          (if (not 
           (string= (substring node (- (string-width node) 1)) "."))
             (jpg-list node))
    (if (string-match ".jpg" node)
        (setq files (cons node files)))))
  files)

i would like to do this without using an external variable (files). What is the idiomatic way of doing this in elisp?

+4  A: 

Your best bet is use 'directory-files full interface and just use:

(directory-files directory t ".jpg$")

The bigger question was how to avoid the top-level variable, which is usually solved by a 'let statement, e.g.

(defun jpg-list (directory)
  (let ((files))
    ...do something with files...
    files))
Trey Jackson
thanks, that solved my problem. But for different situation what is the idiomatic way of writing this kind of loop? using setq all over the place doesn't seem functional code?
Hamza Yerlikaya
if you want a more 'functional' approach you probably want to mapcar over your (directory-files) with a lambda where it recursively calls your function on subdirs.
aaron
Right, mapcar is more functional, but doesn't solve his problem. You would need routines in '`cl` like `'remove-if`, `'remove`, etc. It all depends on what you're doing. The idiomatic way is to use `'directory-files` to its full extent. The next way (with minimal code change) is to use a local variable via '`let', you can write a recursive routine, use `'cl` functions, etc. etc. etc. Note: Emacs isn't functional, it's full of all sorts of side-effects...
Trey Jackson
nice, did not know about this function.
Michael Paulukonis
+2  A: 

Here's my functional solution:

(defun jpg-list (dir)
  (if (file-directory-p dir)
      (append
       (directory-files dir t ".jpg$")
       (apply 'append (mapcar 'jpg-list (directory-files dir t "[^.]+"))))))
Neil