2012-07-16 65 views
1

我已經實現了這個功能。它應該檢查我們提供給它的輸入,如果它在列表中找到,屏幕上將顯示「True」。但是,它只適用於數字,如果我給它一個字符,我收到一個錯誤。如何檢查項目是否是Common Lisp中列表的成員?

(defun element (x lst) 
    (dolist (item lst) 
    (if (= item x) (return t)))) 

我該如何修改它,以便它也可以查找給它的任何字符? 在此先感謝。

回答

1

簡單,使用#情商,而不是#'=,因此3號線就變成了:(if (eq item x) ...

或者,你可以使用內置的#'intersection檢查,如果任何給定的項目是在列表中,這樣的:(if (not (eq (intersection lst '(x)) nil)))

+1

'eql'通常是更好的相等謂詞比'eq'(嘗試,例如,'(列表(=(/ 1 2)(/ 2 4))(當量(/ 1 2)(/ 2 4) )(eql(/ 1 2)(/ 2 4)))'看看結果是否讓你感到意外)。 – Vatine 2012-07-19 10:06:15

+0

這是非常有趣的,謝謝(是的,它讓我感到驚訝:) – 2012-07-19 10:50:10

1

當你發現,the = function只適用於數字。

如果你嘗試find基礎的功能,而不是,你可能會發現,它的默認使用the eql function測試提供你所尋求的行爲:

(defun element (needle haystack) 
    (not (null (find needle haystack)))) 

候補委員到find,你應該還研究其兄弟姐妹memberposition。在你的情況下,因爲你只是想區分已找到的項目,你應該選擇功能最少的功能。我的猜測是position在這裏輸了,那memberfind是等價的; member返回從中提取的car的列表中,而find返回car。在這兩個函數中,都需要提取car

+0

它現在完美,只需用「=」符號替換「eq」。 非常感謝您的善意幫助。 – Momed 2012-07-17 05:42:59

+1

我認爲你的意思是相反的,用「eq。」代替「=」。確保你瞭解'eq','eql','equal','equalp'和kin之間的區別。 – seh 2012-07-17 12:24:47

1

有幾個比較操作。一般的是eq,eql,equalequalp。在hyperspec中查看它們。

對於特定類型的對象,常常出現專門比較器,例如string=char=

最後,列表操作,有喜歡member功能,可以通過手寫循環中解脫出來。他們採用可選test參數,通過該參數您可以傳遞比較功能。

+0

非常感謝。它工作完美。但只有一個問題「eq」功能與「equalp」功能之間有什麼區別? – Momed 2012-07-17 05:41:44

+0

@Momed:http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node74.html那裏你去 – 2012-07-17 15:57:21

相關問題