我是lisp的新手。我正在编写一个递归函数来删除列表中所有出现的元素。
这是我尝试写的只删除列表中的原子出现的内容。
(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))))))
现在,我要对其进行修改,以便它还处理列表中子列表的元素。该函数应该从子列表中删除该元素,并将其保留为子列表(它不应该使子列表变平)。
例 - 输入 -
(my-recursive-remove 'a '((a b) a (c d e a) (a a) b))
预期产出 -
((b) (c d e) nil b))
我知道mapcar可用于将函数应用于列表的所有元素。但我的函数有两个参数,要删除的元素和列表。还有什么方法可以应用mapcar,或者你能建议任何替代方案吗?
我只允许使用基本功能cons
,equal
,defun
,car
,cdr
等。
答案 0 :(得分:2)
mapcar
是一个功能。它是否在您接受的功能列表中?
到目前为止,您的工作可以轻松更改为递归。您需要以不同方式处理原子和列表结构:
(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 <??> <??>)))))
要回答标题问题,请考虑以下代码片段:
(defun test (op n lst)
(mapcar (lambda (e) (funcall op n e))
lst))
(test #'+ 10 '(1 2 3)) ; ==> (11 12 13)
词法范围的主要特征是以前绑定的所有变量在函数创建时都可用。在这里,您可以看到它的行动,因为test
的所有参数都可以在提供给mapcar
的匿名函数中找到
我认为您不应该使用mapcar
,因为如果您发现要删除的元素,您必须返回一个值,它将被放置到位。我看到人们返回一个元素或NIL的列表并使用mapcan
。它与(append (mapcar fun lst))
(mapcan (lambda (x)
(if (= x 1)
nil
(list x)))
'(1 2 3 1 2 3)) ; ==> (2 3 2 3)