1

I have to define a function filter that has as arguments a predicate and a list and returns as value the initial list with THE ONLY ATOMS -for every level of depth- which satisfy the initial predicate (keeping attention at NIL value in order to mantain the list structure).

Example:

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

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

The code i was thinking is like this:

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

How can i implement the depth fact, keeping so the round bracket as displayed in the example?

thank you all

3

1 Answer 1

2

Here is a possible solution:

(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)
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, seems to be close enough to the solution i was looking at

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.