我有以下过滤功能,过滤掉不满足函数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
?
非常感谢。 :)
答案 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)