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

Scheme 将树状列表转换为完整路径列表,scheme,guile,Scheme,Guile,我打算从中使用文件系统树函数 . 与从链接中删除stat相结合,会产生树状列表结构,例如 test/ ├── dir1 ├── dir2 │   ├── file2 │   └── file3 └── file1 我们得到(“test”(“dir2”(“file2”“file3”))“dir1”“file1”) 如何将该列表转换为所有完整路径的列表?这样地 (“test/”“test/file1”“test/dir2”“test/dir2/file3”“test/dir2/file2”“tes

我打算从中使用
文件系统树
函数 . 与
从链接中删除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))))))

希望有帮助

我们需要做的是定义一个递归函数,该函数迭代给定列表的
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))))))

希望有帮助

我来晚了,但我认为这可以用一种比公认的解决方案简单得多(而且可能更快)的方式来完成,使用一种经典的名为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")

我来晚了,但我认为这可以用一种比公认的解决方案更简单(可能更快)的方式来完成,使用一种经典的名为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")

欢迎来到堆栈溢出。你必须更具体一些。到目前为止你都试了些什么?你被困在哪里?请阅读并修改您的问题。欢迎来到stack overflow。你必须更具体一些。到目前为止你都试了些什么?你被困在哪里?请阅读并修改您的问题。谢谢,这正是我想要的,但从未在递归中使用map-on-map。很高兴听到这个消息,@sciamano!实际上,说到地图上的地图,我宁愿找到一种不必嵌套两个非常相似的
map
s的方法。事实上,如果有人知道消除这种情况的好方法,我很想知道。@ChristopherDumas也许可以看看我的答案,它完全避免了
map
。谢谢,这正是我一直在寻找的,但从来没有在递归中使用map-on-map很高兴听到这个消息,@sciamano!实际上,说到地图上的地图,我宁愿找到一种不必嵌套两个非常相似的
map
s的方法。事实上,如果有人知道消除这种现象的好方法,我很想知道。@ChristopherDumas也许可以看看我的答案,它完全避免了
map