2010-06-10 3 views
5

Zastanawiam się, czy istnieje sposób, w jaki mogę zmusić getf do porównania przy użyciu równości zamiast eq? Używam ccl realizacji wspólnego seplenienia.Czy użycie getf może być równe dla porównania zamiast eq? (zwykłe seplenienie)

+1

W najlepszym rozwiązaniem, jednak nie jest to „błąd”: to nie traktuje listę jako pary „kluczowych wartości”, tak że (równej getf „(ABCD)” b) zwraca C while (getf "(abcd)" b) zwraca NIL. Po prostu bądź świadomy tego – ShinTakezou

Odpowiedz

4

Nie. Musisz użyć innej funkcji; coś około jak to może zrobić to, czego potrzebujesz:

(defun equal-getf (plist indicator) 
    (second (member indicator plist :test #'equal))) 

Edycja

Oto ustalona wersja, która traktuje listę odpowiednio jako pary klucz/wartość:

(defun equal-getf (plist indicator) 
    (loop for key in plist by #'cddr 
     for value in (rest plist) by #'cddr 
     when (equal key indicator) 
     return value)) 
0

nie wiem wiedzieć, czy istnieje sposób na "przesłonięcie" wartości domyślnej, sprawdź, czy możesz znaleźć impę przy użyciu (describe 'getf) lub (symbol-plist 'getf). Możliwym semplified realizacja może być

(defun mgetf (l v) 
    (if (< (length l) 2) 
     NIL 
    (if (equal (car l) v) 
     (car (cdr l)) 
    (mgetf (nthcdr 2 l) v))))

EDITED: użyj nthcdr zamiast podwójnej cdr.

+0

bardzo naiwnego implanta w porównaniu do innego rozwiązania ... trochę zardzewiałego z seplem (którego obecnie używam tylko dla emacs ..., gdy jest potrzebny) ... – ShinTakezou

0

To powinno załatwić sprawę. Nie jest ładnie rekurencyjny, ale wykorzystuje prostą aplikację LOOP. Aby umożliwić mu użycie arbitralnego predykatu równoważności, trasa do zastosowania opcjonalnego argumentu powinna być prosta.

(defun mgetf (place indicator) 
    (loop for (key value . rest) on place by #'cddr 
    if (equal key indicator) 
    do (return value))) 
Powiązane problemy