Reputation: 113
I'm a newbie in lisp. I'm writing a recursive function to remove all occurrences of an element in a list.
This is what I tried writing to remove only the occurrences as atoms in the list.
(defun my-remove(x list)
(if(null list)
nil
(if(eql x (car list))
(my-remove x (cdr list))
(cons (car list) (my-remove x (cdr list))))))
Now, I've to modify it such that it also processes the elements of the sublists in the list. The function is expected to remove the element from the sublists and still preserve it as a sublist(It shouldn't flatten out the sublists).
Example- Input -
(my-recursive-remove 'a '((a b) a (c d e a) (a a) b))
Expected output -
((b) (c d e) nil b))
I know that mapcar can be used to apply a function to all elements of a list. But my function takes two arguments, the element to be removed and the list. Is there still any way to apply mapcar, or can you suggest any alternative?
I'm only allowed to use basic functions cons
, equal
, defun
, car
, cdr
etc.
Upvotes: 0
Views: 1575
Reputation: 48745
mapcar
is a function. Is it on your list of accepted functions?
Your work so far can easily be changed to recurse. You need to treat atoms and list structure differently:
(defun my-remove (x list)
(cond ((null list) nil)
((atom (car list))
(if (eql x (car list))
(my-remove x (cdr list))
(cons (car list) (my-remove x (cdr list)))))
(t (cons (my-remove <??> <??>)
(my-remove <??> <??>)))))
To answer your title question, consider this code sniplet:
(defun test (op n lst)
(mapcar (lambda (e) (funcall op n e))
lst))
(test #'+ 10 '(1 2 3)) ; ==> (11 12 13)
The main feature of lexical scope is that all variables previously bound are available at the creation time of a function. Here you see it on action as all arguments to test
are available in the anonymous function supplied to mapcar
I don't think you should use mapcar
for this since wen you find out the elements is to be removed you have to return a value and it will be put in place. I've seen people return lists of one element or NIL and used mapcan
. It's basically the same as (append (mapcar fun lst))
(mapcan (lambda (x)
(if (= x 1)
nil
(list x)))
'(1 2 3 1 2 3)) ; ==> (2 3 2 3)
Upvotes: 2