【问题标题】:mapcar to two argumentsmapcar 到两个参数
【发布时间】:2014-05-28 02:46:44
【问题描述】:

我是 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等

【问题讨论】:

    标签: lisp common-lisp


    【解决方案1】:

    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)
    

    【讨论】:

    • 好的,我明白了。我被允许映射汽车,但现在不需要。谢谢您的帮助。 :)
    猜你喜欢
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-04
    • 1970-01-01
    • 2010-10-12
    相关资源
    最近更新 更多