将树状列表转换为完整路径列表

converting a tree-like list to a full-path-list

我打算使用 file-system-tree 中的函数 https://www.gnu.org/software/guile/manual/html_node/File-Tree-Walk.html#File-Tree-Walk。与 link 中的 remove-stat 相结合,它会产生树状列表结构,例如对于

test/
├── dir1
├── dir2
│   ├── file2
│   └── file3
└── file1

我们得到 ("test" (("dir2" ("file2" "file3")) "dir1" "file1"))

如何将该列表转换为所有完整路径的列表?像这样 ("test/" "test/file1" "test/dir2" "test/dir2/file3" "test/dir2/file2" "test/dir1")

我们需要做的是定义一个递归函数,迭代给定列表的cdrcar,将列表的car附加到字符串项,并在另一个列表元素上调用自身,然后获取返回的项目并将列表的 car 也附加到这些项目上。这是代码中的样子:

(define (tree->full-path-list tree)
  (flatten (append (list (car tree))
                   (map (lambda (x)
                          (if (list? x)
                              (map (lambda (y)
                                     (string-append (car tree) "/" y))
                                   (tree->full-path-list x))
                              (string-append (car tree) "/" x)))
                        (car (cdr tree))))))

希望对您有所帮助!

我来晚了,但我认为这可以比公认的解决方案更容易(也可能更快)地完成,使用经典的 named-let:

(define (path-append part1 part2)
  ;; concatenate paths (lazy man's version)
  (if (non-empty-string? part1)
      (string-append part1 "/" part2)
      part2))

(define (f lst)
  (reverse 
   (let loop ((lst lst) (path "") (res null))
     (if (null? lst)
         res
         (let ((c (car lst)))
           (loop (cdr lst)
                 path
                 (if (list? c)
                     (loop c (car res) res) ; this recurses into sub-lists
                     (cons (path-append path c) res))))))))

不完美,但接近:

> (f '("test" (("dir2" ("file2" "file3")) "dir1" "file1")))
'("test" "test/dir2" "test/dir2/file2" "test/dir2/file3" "test/dir1" "test/file1")