LISP处理讨厌的NIL

时间:2012-02-21 03:15:07

标签: lisp null

我有以下过滤功能,过滤掉不满足函数f的列表x。

例如,我致电(filter 'evenp '(0 1 2 3))并返回(NIL 1 NIL 3)。但这正是我的问题。我该怎么做才能让我回来(1 3)

(defun filter (f x)
    (setq h (mapcar #'(lambda (x1)
                        (funcall f x1))
                    x))
    (mapcar #'(lambda (a b)
                (cond ((null a) b)))
            h x))

即。问题就在这里:(lambda (a b) (cond ( (null a) b) ) )在我的cond我没有t或其他声明,所以不应该只是停在那里而不是返回{{1} }?如果不满足nil,如何使其“返回”,甚至不nil

非常感谢。 :)

3 个答案:

答案 0 :(得分:3)

基于this question,它将是:

(remove-if #'evenp '(0 1 2 3))

答案 1 :(得分:1)

忽略这篇文章提出的其他问题,我会说mapcar总会为它映射的每个东西返回一些东西,所以你不能使用另一个mapcar来清理NILs那里。这就是mapcar所做的事情 - 它遍历项目(或项目,如果在多个列表上进行映射,就像您的第二次尝试mapcar那样)并收集在这些参数上调用某些函数的结果。< / p>

相反,在这种情况下,如果由于某种原因必须使用mapcar,并且不想使用NIL,则可以使用remove函数,即(remove nil (mapcar ...))

由于@ stark的答案在上面发布,我会说remove-if函数基本上就是你在这里尝试实现的。 (这就是问题,这是否与家庭作业最相关。)

答案 2 :(得分:1)

要回答如何将任意数量的项目(包括根本没有项目)拼接到结果中的更一般的问题,mapcan(在语义上mapcar + append)是对此有用:

(defun filter (f xs)
  (mapcan (lambda (x)
            (if (funcall f x)
                (list x)
                nil))
          xs))
当您想要将项目映射到多个结果时,

mapcan也很有用:

(defun multi-numbers (xs)
  (mapcan (lambda (x) (list x (+ x x) (* x x))) xs))

(multi-numbers (list 1 2 3))
;=> (1 2 1 2 4 4 3 6 9)