Johan14th
Johan14th

Reputation: 117

Remove an element from a list in Common Lisp?

I am currently trying to remove any NIL I find from a list (recursively) on all levels. I already know how to remove NIL from the top level of a list, and I thought much of the idea would be the same when dealing with multiple levels, however, I have run into a snag.

My code for removing Nil from the top level:

(defun removeNILTop (L)
    (cond ( (NULL L) NIL) ;;list is empty
          ( (NULL (CAR L)) (removeNILTop( CDR L))) ;;Nil so skip it
          ( T (CONS( CAR L) (removeNILTop( CDR L)))) ;;not NIL so include it
    )
)

This my code for removing Nil from all levels:

  (defun removeAll (l)
        (cond
            ((null l) NIL) ;;empty list
            ((null (car l)) (removeAll(cdr l))) ;;Nil so skip it
            ((atom (car l)) (cons (car l) (removeAll(cdr l)))) ;;not nil and is a atom so continue normally
            (T (cons( removeAll(car l) (removeAll(cdr l))))) ;;car is a list recurse into it
        )

    )

The way I was thinking about this is that in the first example I ignore what the car of the list and just keep it as long as it's not null. However, now that I care about it, I should check if the car is

This obviously is however not working, any tips?

Upvotes: 0

Views: 3415

Answers (2)

Gwang-Jin Kim
Gwang-Jin Kim

Reputation: 10085

(defun removeAll (l)
  (cond ((null l) NIL)
        ((null (car l)) (removeAll(cdr l))) 
        ((atom (car l)) (cons (car l) (removeAll (cdr l)))) 
        (T (cons (removeAll (car l)) (removeAll (cdr l))))))

You forgot to close in the last claus the first removeAll on (car l) with a paranthesis.

You can avoid such mistakes by using an editor which supports paranthesis automatic filling. And indents the code automatically. What editor you use?

Upvotes: 2

Svante
Svante

Reputation: 51551

You have three cases regarding the car now. Looking at it from the perspective of the current cell:

  • The car of the current cell is nil
  • The car of the current cell is an atom (and not null)
  • The car of the current cell is a list

Regarding the cdr, assuming nested proper lists, it will always be either a cons cell or nil.

You need to recurse on possibly both car and cdr when they are conses.

Regarding naming: standard behaviour of the Lisp reader is to upcase everything, so the names you are showing are actually REMOVENILTOP and REMOVEALL. The convention is to write lower case names with parts separated by dashes: remove-nil-top, remove-all. I like the names remove-nil and tree-remove-nil better, by the way.

Upvotes: 3

Related Questions