tags:

views:

93

answers:

3

I want to write a function in LISP that will completely remove all NILS in a list. The list may be nested, meaning it can contain other lists inside. For example the list '((state L L L L) NIL (state L L R L) NIL) should be tranformed into '((STATE L L L L) (STATE L L R L)).

+4  A: 
(defun remove-nil-recursively (x)
  (if (listp x)
    (mapcar #'remove-nil-recursively
            (remove nil x))
    x))

Works for your example:

[1]> (remove-nil-recursively '((state L L L L) NIL (state L L R L) NIL))
((STATE L L L L) (STATE L L R L))

And with nested lists:

[2]> (remove-nil-recursively '(NIL (state L L nil R L) NIL))
((STATE L L R L))

But watch out:

[3]> (remove-nil-recursively '(NIL (state L L (nil) R L) NIL))
((STATE L L NIL R L))
larsmans
A: 

A generic function in the style of remove-if:

(defun remove-all (predic seq &optional res)
  (if (null seq)
      (reverse res)
      (cond ((and (not (null (car seq))) (listp (car seq)))
             (remove-all predic (cdr seq)
                         (cons (remove-all predic (car seq)) res)))
            ((funcall predic (car seq))
             (remove-all predic (cdr seq) res))
            (t (remove-all predic (cdr seq) (cons (car seq) res))))))

Examples:

>  (remove-all #'null (list 1 2 'nil 3))
=> (1 2 3)
>  (remove-all #'null (list 1 2 'nil '(4 5 nil 6) 3))
=> (1 2 (4 5 6) 3)
>  (remove-all #'(lambda (x) (oddp x)) '(1 2 (3 4) 5 6 (7 8 (9 10))))
=> (2 (4) 6 (8 (10)))
Vijay Mathew
+1  A: 

Paul Graham calls this function (recurring into sublists remove-if) "prune" in On Lisp, p. 49. It is one of the utility functions.

Dmitri Pavlenkov