2010-06-10 29 views
5

Tôi tự hỏi nếu có một cách mà tôi có thể buộc getf để so sánh bằng cách sử dụng bằng nhau thay vì eq? Tôi đang sử dụng ccl thực hiện chung lisp.Có thể sử dụng getf để so sánh thay vì eq không? (phổ biến lisp)

+1

Tuy nhiên, giải pháp tốt nhất có "lỗi": không coi danh sách là "giá trị khóa", để (bằng-getf '(abcd)' b) trả về C trong khi (getf '(abcd)' b) trả về NIL. Chỉ cần nhận thức được điều này – ShinTakezou

Trả lời

4

No. Bạn phải sử dụng một chức năng khác; một cái gì đó xấp xỉ như thế này có thể làm những gì bạn cần:

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

Sửa

Dưới đây là một phiên bản cố định mà đối xử với danh sách đúng như cặp khóa/giá trị:

(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

tôi không biết nếu có cách để "ghi đè" mặc định, hãy xem bạn có thể tìm thấy một impl sử dụng (describe 'getf) hoặc (symbol-plist 'getf) hay không. Một thực hiện semplified thể có thể là

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

EDITED: sử dụng nthcdr thay vì cdr đôi.

+0

impl rất ngây thơ so với các giải pháp khác ... một chút gỉ với lisp (mà hiện tại tôi chỉ sử dụng cho emacs ..., khi cần thiết) ... – ShinTakezou

0

Điều này sẽ thực hiện công việc. Nó không phải là đệ quy độc đáo, nhưng sử dụng một ứng dụng LOOP thẳng về phía trước. Để cho phép nó ti sử dụng một vị từ tương đương tùy ý, tuyến đường để sử dụng một đối số tùy chọn nên thẳng về phía trước.

(defun mgetf (place indicator) 
    (loop for (key value . rest) on place by #'cddr 
    if (equal key indicator) 
    do (return value))) 
Các vấn đề liên quan