2013-10-21 53 views
0

我想創建具有符號/記號和Lisp的 - 檢查如果一個符號在列表

傳遞給函數列表,然後將檢查如果列表中包含的符號的功能列表/令牌。如果是這樣,則返回其對應的密鑰對,如果不返回NUL

我做了一個defparameter這是:

(defparameter *pairs* 
    '((apple green) 
    (banana yellow) 
    (grape purple))) 

然後我做了一個函數做任務:

(defun list-pairs (word list) 
    (if (eq word list) 
    (rest(list))) 
    nil)) 

函數時執行如此:(list-pairs '(banana) *pairs*)我不斷收到nul

我想要返回的是黃色即密鑰對

有人可以幫我解釋什麼是錯的。我是很新的LISP

+0

爲什麼不使用LISP散列機制,如下所述:http://stackoverflow.com/questions/1837438/can-you-have-hash-tables-in-lisp/1837533#1837533 – lurker

+0

其原因我只是剛開始學習lisp,所以即時通訊只是嘗試使用基礎知識來完成任務,然後再使用一些更高級的東西:)即使用defun,if語句,缺點,第一,休息zerop,numberp等 –

回答

1

你在找什麼是

(defun list-pairs (word list) 
    (if list 
    (if (eq (caar list) word) 
     (cadar list) 
     (list-pairs word (cdr list)))))) 

,或者使用我們作爲一個小的優化:

(defun list-pairs (word list) 
    (if list 
    (let ((c (car list))) 
     (if (eq (car c) word) 
     (cadr c) 
     (list-pairs word (cdr list)))))) 

,其與Common Lisp的實現,它尾巴效果很好呼叫優化;你應該使用它像

(list-pairs 'banana *pairs*) 

但Common Lisp中循環宏通常優選:

(defun list-pairs (word list) 
    (loop for c in list 
    when (eq (car c) word) 
    return (cadr c))) 
4
(second (assoc 'banana *pairs*)) 

YELLOW 

編輯:請參見下面約書亞·泰勒的評論有關assoc和as的概念的文檔(或簡稱:alist)它的工作原理(很簡單:10 alist是一個鍵值數據結構,由cons單元格列表組成,其中每個cons單元格的car是關鍵字,cdr是值)。

關於什麼是錯用自己的代碼:

在你if的條件:(eq word list),您正在測試是否你的論點word是一樣的你的論點list。但是您實際上想要在list範圍內尋找word,這樣就不能成爲正確的條件。

此外,即使條件屬實,您要評估的是(rest(list))。這是通過調用函數list創建的新空列表的其餘部分,而不是您的參數list的其餘部分。

最後,您將在(rest(list))之後關閉if表達式,並在那裏顯示第三個右括號。因此,最後的nil將是您的函數的返回值,即使其他所有內容都是正確的。您需要將nil移到if表達式的括號中,以使其成爲else結果,並將if表達式的值作爲該函數的返回值。

+0

我很高興看到' assoc'提到,特別是我認爲它被視爲「Lisp基礎」之一。我不介意看到關於[關聯列表](http://www.lispworks.com/documentation/HyperSpec/Body/14_aba.htm)是什麼的一些討論,以及什麼['assoc'](http: //www.lispworks.com/documentation/HyperSpec/Body/f_assocc.htm)does ... –

+0

@JoshuaTaylor:同意,如果我添加了「assoc」的解釋,會更好。感謝您提供CLHS的鏈接,我會在我的回答中添加對您評論的引用。 (我沒有這樣做的一個原因正是因爲我認爲Lisp的每一個像樣的入門都應該提到這是一個基礎。) –

1

作爲另一個備選方案:

(defun list-pairs (word list) 
    (dolist (p list) 
    (if (eq word (first p)) 
     (return (second p))))) 

(defparameter *pairs* 
    '((apple green) 
    (banana yellow) 
    (grape purple))) 

(list-pairs 'banana *pairs*) 
YELLOW 
0

你的任務留下了一些問題,向我敞開。

1.)你的函數應該得到一個符號。但你爲什麼這樣稱呼它:(list-pairs '(banana) *pairs*)(list-pairs 'banana *pairs*)足夠嗎?

2.)你只想得到配對的第一個元素的匹配?即您是否想要符號bananayellow的結果相同?

如果你只想搜索第一個元素,Rörd已經提到assoc,這將是完美的。 如果你想檢查這兩個元素,你可以試試remove-if-not

(defun list-pairs (word list) 
    (remove-if-not 
    #'(lambda (sublist) (member word sublist)) 
    list))