鉴于我的列表可能会有所不同。结构 - 列表中可能有多个列表,如何遍历每个元素? 列表示例:(或(和(不是)(非b))(或(和x)t)))
答案 0 :(得分:2)
这是maptree功能的典型情况。
(defun maptree (fn tree)
(cond
((null tree) tree)
((atom tree) (funcall fn tree))
(t (cons
(maptree fn (first tree))
(maptree fn (rest tree))))))
所以你可以做(maptree #'what-to-do your-list)
。
我只打印所有元素,你可以提供你想要的任何功能,它会在树的每个元素上执行。
CL-USER> (let ((lis
'(or (and (not a) (not b)) (or (and x) t))))
(maptree #'print lis))
OR
AND
NOT
A
NOT
B
OR
AND
X
T
答案 1 :(得分:0)
这是递归函数的一个很好的例子。你可能想要这样的东西:
(defun iterate (l) (if (atom l) (do-something-with l) (mapcar #'iterate l)))
函数do-something-with明确定义了你想要对每个元素做什么。此外,mapcar可以被另一个映射函数替换,具体取决于你是否要累积do-something-with的结果。
答案 2 :(得分:0)
来自SICP我记得accumulate-tree
,它可以被认为是reduce
树。在CL中它可能看起来像这样:
(defun accumulate-tree (tree term combiner null-value)
(labels ((rec (tree)
(cond ((null tree) null-value)
((atom tree) (funcall term tree))
(t (funcall combiner (rec (car tree))
(rec (cdr tree)))))))
(rec tree)))
你可以做一些事情,比如在树中添加所有数字:
(defparameter *value-tree* '(1 2 (3 4 (5 6)) 3))
(accumulate-tree *value-tree*
(lambda (x) (if (numberp x) x 0))
#'+
0) ; => 24
要实施@coredumps map-tree
,您可以使用cons
作为合并器,并使用nil
ass nil值:
(defun map-tree (function tree)
(accumulate-tree tree function #'cons nil))