2008-09-01 47 views
7

我發現自己一直在做這種事情。我一直在考慮編寫一個宏/函數來使這種事情變得更容易,但是對我而言,我可能會重新發明輪子。常見的lisp成語 - 有沒有更好的方法?

是否有一個現有的函數可以讓我更簡潔地完成同樣的事情?

(defun remove-low-words (word-list) 
    "Return a list with words of insufficient score removed." 
    (let ((result nil)) 
    (dolist (word word-list) 
     (when (good-enough-score-p word) (push word result)))          
    result)) 

回答

23

有幾種內置方式可以做到這一點。一種方法是:

(remove-if-not 'good-enough-score-p word-list) 

而另:

(loop for word in word-list 
     when (good-enough-score-p word) 
     collect word) 

而另一個:

(mapcan (lambda (word) 
      (when (good-enough-score-p word) 
      (list word))) 
     word-list) 

等......還有SERIESIterate。該迭代版本是相同的LOOP版本,但該系列的版本是有趣:

(collect (choose-if 'good-enough-score-p (scan word-list)))) 

所以,是的,你很可能會重塑一些輪。 :-)

+0

謝謝 - 我從來沒有真正想過使用mapcan的理由,但這顯示了我的方式。對於這個特定的例子,remove-if/remove-if-not更好,但仍然非常好。 – khedron 2009-12-08 01:59:12

-2

有幾種方法可以做到這一點。首先,也許最容易,你可以遞歸地做。

(defun remove-low-words (word-list) 
    (if (good-enough-score-p (car word-list)) 
     (list word (remove-low-words (cdr word-list))) 
     (remove-low-words (cdr word-list)))) 

你也可以用mapcarreduce,其中前者可以構建你與nil更換故障元件,後者可以用來濾除nil列表做到這一點。

要麼是一個「過濾器」宏或函數的一個很好的候選者,它會接受一個列表並返回由某個謂詞過濾的列表。

+0

我相信你的版本沒有基礎的情況下,其他方面的問題。 – 2008-09-18 08:20:05

相關問題