LISP 过滤函数

LISP filter function

我必须定义一个函数filter,它有一个谓词和一个列表作为参数,returns作为初始列表的值,只有原子 - 对于每个深度级别 - 满足初始谓词(注意 NIL 值以维护列表结构)。

示例:

(filter 'evenp '(24 5 (7) d (((4))) 3 ()))

(24 () (((4))) ())

我想的代码是这样的:

(defun filter (pred list)
  (cond ((null list) nil)
        ((funcall pred (car list))
         (cons (car list)
               (filter pred (cdr list))))
        (T (filter pred (cdr list)))))

如何实现深度事实,同时保持示例中显示的圆括号?

谢谢大家

这是一个可能的解决方案:

(defun filter (predicate x)
   (if (consp x)  ; if x is a cons, that is a tree:
       (let ((ca (car x))
             (cd (filter predicate (cdr x)))) ; filter always the cdr
         (if (listp ca)                       ; if the car of x is a list (nil or cons)
             (cons (filter predicate ca) cd)  ; then filter also the car
             (if (funcall predicate ca) (cons ca cd) cd))) ; car is a non-nil atom!
       x))        ; if x is a atom (nil or the last cdr of an improper list), return x

CL-USER> (filter 'evenp '(24 5 (7) 5 (((4))) 3 ()))
(24 NIL (((4))) NIL)