使用LISP迭代列表中的每个项目

时间:2015-12-07 23:08:34

标签: list lisp iteration

鉴于我的列表可能会有所不同。结构 - 列表中可能有多个列表,如何遍历每个元素? 列表示例:(或(和(不是)(非b))(或(和x)t)))

3 个答案:

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