2008-09-01 27 views
7

Ich finde mich die ganze Zeit so etwas zu tun. Ich habe darüber nachgedacht, ein Makro/eine Funktion zu schreiben, um so etwas einfacher zu machen, aber mir fällt ein, dass ich das Rad wahrscheinlich neu erfinde.Common Lisp Idiom - gibt es einen besseren Weg?

Gibt es eine bestehende Funktion, die mir diese Art von Sache prägnanter erreichen wird?

(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)) 

Antwort

23

Es gibt mehrere integrierte Möglichkeiten, dies zu tun. Eine Möglichkeit wäre:

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

Und ein anderer:

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

Und noch eine andere:

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

Etc ... Es gibt auch SERIES und Iterate. Die Iterate Version ist identisch mit der LOOP-Version, aber die Serienversion ist interessant:

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

Also, ja, sind Sie sehr wahrscheinlich einige Rad neu zu erfinden. :-)

+0

Danke - Ich habe noch nie einen Grund gefunden mapcan zu benutzen, aber das zeigt mir den Weg. In diesem speziellen Beispiel ist remove-if/remove-if-not besser, aber trotzdem sehr nett. – khedron

-2

Es gibt ein paar Möglichkeiten, wie Sie dies tun können. Erstens, und wahrscheinlich am einfachsten, können Sie es rekursiv tun.

(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)))) 

Sie können es auch tun, mit mapcar und reduce, wo der ehemalige eine Liste mit versagenden Elemente durch nil und dieser ersetzt konstruieren kann, kann verwendet werden, die nil auszufiltern.

Entweder wäre ein guter Kandidat für ein "Filter" -Makro oder -Funktion, die eine Liste übernimmt und die durch ein Prädikat gefilterte Liste zurückgibt.

+0

Ich glaube, Ihre Version keine Basisfall, unter anderem Probleme hat. –

Verwandte Themen