2010-12-05 5 views
0

У меня есть следующие Common Lisp функции:Есть ли лучший способ написать эту функцию?

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

Вот что board есть и вот выход функции:

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

Похоже, что функция, которую я написал может быть немного многословным. Есть ли более сжатый способ написать его?

ответ

7

Я бы написал это так, переходя в список, который нужно искать, а не используя глобальную переменную board. Я бы также добавить строку документации, а с помощью eq для сравнения кажется довольно произвольным, я бы сделал это аргументом ключевого слова, чтобы вы могли поставить = для числового сравнения или equal строк:

(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) 
Смежные вопросы