2008-09-01 11 views
7

Me encuentro haciendo este tipo de cosas todo el tiempo. He estado considerando escribir una macro/función para facilitar este tipo de cosas, pero se me ocurre que probablemente estoy reinventando la rueda.Lenguaje de lisp común: ¿hay una manera mejor?

¿Existe una función existente que me permita lograr este mismo tipo de cosas de manera más sucinta?

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

Respuesta

23

Existen varias formas incorporadas de hacerlo. Una forma sería:

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

Y otro:

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

Y otro:

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

etc ... También hay SERIES y Iterate. La versión Iterar es idéntica a la versión LOOP, pero la versión de serie es interesante:

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

Así que, sí, es muy probable que reinventar alguna rueda. :-)

+0

Gracias, nunca he tenido una razón para usar mapcan antes, pero esto me muestra el camino. Para este ejemplo en particular, remove-if/remove-if-not es mejor, pero aún así, muy agradable. – khedron

-2

Hay varias formas de hacerlo. Primero, y probablemente más fácilmente, puedes hacerlo recursivamente.

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

También podría hacerlo con mapcar y reduce, donde el primero se puede construir una lista con los elementos que fallan reemplazados por nil y el último puede ser utilizado para filtrar el nil.

Cualquiera de los dos sería un buen candidato para una macro o función de "filtro" que toma una lista y devuelve la lista filtrada por algún predicado.

+0

Creo que su versión no tiene caso base, entre otros problemas. –

Cuestiones relacionadas