2017-10-29 106 views
0

假設我想從狀態列表中刪除一個步驟(元素)。多於一個參數用於刪除謂詞 - 如果

(defparameter *states* '((:top nil nil) (:subjects nil nil))) 
;predicate 
(defun equal-state? (step state) 
    (equal (car step) state)) 

如果我使用(delete-if #'equal-state? *states*)那麼如何在第二個參數(state)可以傳遞給謂詞?

編輯:我終於找到了一個類似的問題,但我傾向於保留它,因爲問題的清晰。

+1

NB。在這個例子中,你正在使用DELETE,它有權改變數據,但你的數據是常量(引用列表),不應該在便攜式程序中修改。 – coredump

回答

3
CL-USER 67 > (let ((state :top)) 
       (delete-if (lambda (step) 
          (equal-state? step state)) 
          *states*)) 
((:SUBJECTS NIL NIL)) 

CL-USER 68 > (defun make-predicate (state) 
       (lambda (step) 
       (equal-state? step state))) 
MAKE-PREDICATE 

CL-USER 69 > (delete-if (make-predicate :subjects) 
         *states*) 
((:TOP NIL NIL)) 

作爲用戶信息轉儲提到,delete-if是一個潛在的破壞性操作。 delete-if的非破壞性替代品是remove-if

你也可以使用remove/delete

CL-USER 77 > (remove :subjects 
        '((:top nil nil) 
         (:subjects nil nil)) 
        :key #'first 
        :test #'equal) 
((:TOP NIL NIL)) 
+0

@coredump暗示,不應該在便攜式程序中修改常量數據......我的lisp實現也會警告我有關常量數據的問題..我無法將自己的頭圍繞在它上面......以及「便攜式程序中的常量數據?」 –

+1

@BilalQadri:如果你的程序中寫有'(a b c)',它就是一個引用列表。這個列表是文字數據。沒有指定如果你修改它會發生什麼。可以工作,可能有副作用,可以默默地失敗,可能會導致錯誤。未指定。一個新的清單將被創建,具有LIST,COPY-LIST等許多功能。如果您向REPL鍵入文字列表,您可以在不看到問題的情況下對其進行修改,但通常情況並非如此。特別是在編譯代碼中,它可能會導致問題。這不是Lisp特有的。其他朗也有類似的問題。 –