2012-02-21 91 views
1

我有以下的過濾器函數,它過濾掉不滿足函數f的列表x。LISP處理討厭的NIL

例如,我撥打(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,或者else語句,所以不應該只是停在那兒,而不是返回nil?我如何使它「返回」什麼都沒有,如果(cond ((null a) b))不滿意,甚至不是nil

非常感謝。 :)

+2

'h'是一個不確定的變量。你需要定義它。另外,這功課呢? – 2012-02-21 03:46:33

+0

懷疑'h'應該在'let'裏面;看起來海報試圖將其用作中間存儲,然後將空值從中過濾出來。 – khedron 2012-02-21 03:57:52

回答

1

無視這篇文章提出的其他問題,我會說mapcar將永遠爲它的映射在每一件事情返回的東西,這樣你就可以」 t用另一個mapcar清理那裏的NIL。這就是mapcar所做的 - 它遍歷項目(或項目,如果映射到多個列表,如第二次嘗試mapcar所做的那樣)並收集在這些參數上調用某個函數的結果。

相反,在這種情況下,如果你不得不使用mapcar出於某種原因,並沒有想的近等基因系,您可以使用remove功能,即(remove nil (mapcar ...))

自@鮮明的答案是上面貼的,我我會說remove-if函數基本上是你在這裏試圖實現的。 (這就是這是否是家庭作業的問題變得最爲重要。)

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)