Common Lisp - 从嵌套的列表列表中收集“第一”

时间:2014-11-19 19:14:07

标签: list tree common-lisp

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"))

提前致谢!

2 个答案:

答案 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*)