Lisp 如何使用MAPCAR实现REMOVE-IF

Lisp 如何使用MAPCAR实现REMOVE-IF,lisp,common-lisp,Lisp,Common Lisp,如何使用MAPCAR函数在Common Lisp中以非递归方式实现与REMOVE-IF等效的函数?使用MAPCAR是不可能的,因为它总是返回与输入长度相同的列表(如果某些输入元素满足谓词,则需要较短的列表) 但是可以使用相关功能MAPCAN。如果你 将谓词应用于每个元素X。 如果X满足谓词,则替换(X)如果X不满足谓词,则替换NIL 连接结果列表 然后,您将获得一个列表,其中包含不满足谓词的元素(根据需要) MAPCAN将结合这些操作,给定一个实现步骤1的函数 例如: (defun list-i

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

使用
MAPCAR
是不可能的,因为它总是返回与输入长度相同的列表(如果某些输入元素满足谓词,则需要较短的列表)

但是可以使用相关功能
MAPCAN
。如果你

  • 将谓词应用于每个元素
    X
    • 如果
      X
      满足谓词,则替换
      (X)
    • 如果
      X
      不满足谓词,则替换
      NIL
  • 连接结果列表
  • 然后,您将获得一个列表,其中包含不满足谓词的元素(根据需要)

    MAPCAN
    将结合这些操作,给定一个实现步骤1的函数

    例如:

    (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
    本身无法做到这一点,尽管您可以将其与
    ncoc
    (或
    APPEND
    )结合使用以获得相同的结果:

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

    使用
    mapcar
    无法执行此操作
    mapcar
    返回使用输入列表的每个元素调用函数的结果列表。如果元素与过滤函数匹配,则无法将其中一个元素省略。
    (应用#“append(mapcar#”)(lambda(x)(if(=x 17)nil(list x))(list 17 71))
    ==>
    (17 71)