Beeing是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"))
提前致谢!
答案 0 :(得分:1)
这样的事情怎么样?
(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))
CL-USER> (immediate-children *nested-list*)
(("a" "b" "e") ("e" "f" "g") ("g" "h") ("f") ("b" "c") ("c" "d"))
结果并不完全是你在问题中提供的结果,但我认为它仍然有意义。它在结果中包含("f")
,这可能是合理的,因为标记为"f"
的节点没有子节点。遍历顺序也不同,但如果这只是(parent child+)
形式的列表列表,那么这可能不是问题。
答案 1 :(得分:0)
我在emacs和common-lisp中测试过以下内容。 可以在https://ideone.com/hNEQTJ检查输出。
(defparameter *nested-list* (list "a" (list "b" (list "c" "d"))
(list "e" (list "f")
(list "g" "h"))))
(defun collect-firsts (*nested-list*)
(let ((ret `((start ,(car *nested-list*)))))
(labels ((recursion (x)
;; 1st generate list of the name and the cars
(setq ret (append ret
(list (cons (car x)
(mapcar (lambda (el)
(if (listp el) (car el) el))
(cdr x))))))
;; 2nd recurse if required
(mapc (lambda (el)
(when (and (listp el) (cdr el))
(recursion el))) x)
ret))
(recursion *nested-list*)
ret)))
(collect-firsts *nested-list*)