List 公共Lisp-Collect';第一';从列表的嵌套列表

List 公共Lisp-Collect';第一';从列表的嵌套列表,list,tree,common-lisp,List,Tree,Common Lisp,我是CL的新手,尝试了几种映射方法,但仍然无法理解 是否可以从嵌套列表中收集所有第一个元素,如下所示?从概念上讲: 如何从CL中的一个(不一定是二进制的)树状结构中收集父节点及其所有子节点 (defparameter *nested-list* (list "a" (list "b" (list "c" "d")) (list "e" (list "f")

我是CL的新手,尝试了几种映射方法,但仍然无法理解

是否可以从嵌套列表中收集所有第一个元素,如下所示?从概念上讲: 如何从CL中的一个(不一定是二进制的)树状结构中收集父节点及其所有子节点

(defparameter *nested-list* (list "a" (list "b" (list "c" "d"))
                                      (list "e" (list "f")
                                                (list "g" "h"))))
函数调用

(defun collect-firsts (*nested-list*)
  ; ...
)
…结果应该是这样的:

:-> (('start "a") ("a" "b" "e") ("b" "c") ("c" "d")
     ("e" "f" "g")("f") ("g" "h"))

提前谢谢

像这样的怎么样

(defun immediate-children (object &aux (result '()))
  (labels ((f (object) 
             (cond
               ((consp object)
                (push (list* (first object)
                             (mapcar #'f (rest object)))
                      result)
                (first object))
               (t object))))
    (f object)
    result))


结果并不完全是你在问题中提供的,但我认为它仍然有意义。它在结果中包含
(“f”)
,这可能是合理的,因为有一个标记为
“f”
的节点没有子节点。遍历顺序也不同,但如果这只是一个列表,其形式为
(父-子+
),那么这可能不是问题。

我已经在emacs和common lisp中测试了以下内容。 可在以下位置检查输出

(defparameter*嵌套列表*(列表“a”(列表“b”(列表“c”和“d”))
(列表“e”(列表“f”)
(列表“g”和“h”))
(取消收集第一个(*嵌套列表*)
(let((ret`((开始,(车*嵌套列表*)))))
(标签)(递归(x)
第一次生成姓名和车辆的列表
(setq ret(附加ret)
(列表(cons)(车辆x)
(地图车(lambda(el)
(如果(列表el)(汽车el)el)
(cdr x(()()))
如果需要,第二次递归
(mapc(lambda(el)
(何时(和(列表el)(cdr el))
(递归el)))x)
ret)
(递归*嵌套列表*)
(ret)
(收集第一个*嵌套列表*)

请不要这样做。这几乎就像用C#或JavaScript回答Java问题一样。@PauloMadeira感谢您通知我代码没有在CL中运行。我已经修改了它,使它在CL中以及emacs lisp中运行。不要在Common lisp中使用
setq
未绑定变量。它有未定义的行为,特别是关于结果变量的特殊性。在这里,
defparameter
似乎是正确的。
defparameter
似乎适合顶层,也就是说。使用
放在车身内部。如果你根据代码的结构来格式化代码,它也会变得更容易理解(我不知道你在用
ret
做什么)。当然你对附加(“f”)的看法是正确的,我已经更正了输出。非常感谢!
CL-USER> (immediate-children *nested-list*)
(("a" "b" "e") ("e" "f" "g") ("g" "h") ("f") ("b" "c") ("c" "d"))