将树状列表转换为完整路径列表
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")
我们需要做的是定义一个递归函数,迭代给定列表的cdr
的car
,将列表的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")
我打算使用 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")
我们需要做的是定义一个递归函数,迭代给定列表的cdr
的car
,将列表的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")