mapcar到两个参数

时间:2014-04-14 08:09:44

标签: lisp common-lisp

我是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,或者你能建议任何替代方案吗?

我只允许使用基本功能consequaldefuncarcdr等。

1 个答案:

答案 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)