如何使用MAPCAR实现REMOVE-IF

时间:2012-11-07 05:26:19

标签: lisp common-lisp

如何使用MAPCAR函数在Common Lisp中实现等效于REMOVE-IF非递归的函数?

1 个答案:

答案 0 :(得分:4)

MAPCAR无法实现,因为它总是返回与输入长度相同的列表(如果某些输入元素满足谓词,则需要更短的列表。)

但是可以使用相关函数MAPCAN。如果你

  1. 将谓词应用于每个元素X
    • 如果X满足谓词,请替换(X)
    • 如果X不满足谓词,请替换NIL
  2. 连接结果列表
  3. 然后根据需要,你将得到一个包含不满足谓词的元素的列表。

    在给定实现步骤#1的函数的情况下,

    MAPCAN将组合这些操作。

    示例:

    (defun list-if-not (pred)
      (lambda (x) (if (funcall pred x) nil (list x))))
    
    (defun my-remove-if (pred lst)
      (mapcan (list-if-not pred) lst))
    
    (my-remove-if #'evenp '(1 2 3 4 5))
    

    ==> (1 3 5)

    单独

    MAPCAR无法执行此操作,但您可以将其与NCONC(或APPEND)结合使用,以获得相同的结果:

    (defun my-remove-if (pred lst)
      (apply #'nconc (mapcar (list-if-not pred) lst)))