2010-12-05 42 views
0

J'ai la fonction Common Lisp suivante:Existe-t-il un meilleur moyen d'écrire cette fonction?

(defun get-positions (marker) 
    (let ((result nil)) 
    (dotimes (i (length board)) 
     (if (eq (nth i board) marker) 
      (push i result))) 
    (nreverse result))) 

Voici ce que board est et est ici la sortie de la fonction:

CL-USER> board 
(X X O NIL NIL NIL NIL NIL NIL) 
CL-USER> (get-positions 'x) 
(0 1) 

Il semble que la fonction que j'ai écrit peut-être un peu bavard. Y a-t-il une façon plus concise de l'écrire?

Répondre

7

Je l'écrirais comme ceci, passant dans la liste à rechercher plutôt que d'utiliser la variable globale board. Je voudrais aussi ajouter un docstring, et puisque l'utilisation eq de comparaison semble plutôt arbitraire, je ferais un argument de mot-clé pour que vous puissiez fournir = pour la comparaison numérique ou equal pour les chaînes:

(defun get-positions (x list &key (test #'eq)) 
    "Return list of indexes of positions where X appears in LIST. 
Keyword :test specifies the comparison function (default: EQ)." 
    (loop for y in list 
     for i upfrom 0 
     if (funcall test x y) collect i)) 

(get-positions 'x '(x x nil nil x nil x)) 
    ==> (0 1 4 6)