2010-08-13 61 views
5

我在尋找一種方式來「啪」從關聯列表中的元素,換句話說是「破壞性的」 assoc命令:在口齒不清從關聯列表託一個元素(elisp的)

(setq alist '((a . 1) (b . 2)) 
(assoc-pop 'a alist) ;; -> (a . 1) 
;; alist -> ((b . 2)) 

是在elisp線束中有沒有任何功能? 獲得同類功能的最優雅方式是什麼? (不知道這種「副作用」是一種很好的做法,即使這是可能的!)

回答

3

沒有這樣內置的操作,我知道的,但我認爲你可以很快得到這個功能:

(defmacro assoc-pop (key alist) 
    `(let ((result (assoc ,key ,alist))) 
    (setq ,alist (delete result ,alist)) 
    result)) 
1

assq-delete-all接近你想要的。它按對象標識(eq)查找元素,而不是按值相等(equal)。它刪除所有匹配的元素,而不僅僅是第一個。它返回修改後的列表。你可以調整這個函數的代碼來做你想做的事情。 (但是,如果你要調用assoc-pop在一個循環中,所有的鍵符號,assq-delete-all做所有你需要的。)

注意"a"'a是完全不同的對象:第一個是字符串,第二個是一個符號。所以你的第二行應該是(assoc-pop 'a alist)

但實際上,調用(assoc-pop 'a alist)不能工作(除非assoc-pop是一個宏),因爲它不能刪除列表中的第一個元素。您可以製作一個函數,它將一個符號作爲參數,並根據add-to-list的模型修改符號值的列表。你可以稱它爲(assoc-pop 'a 'alist)

+0

也謝謝關於符號的地步,我是新聆聽,我還沒有掌握符號/列表/ other_things的東西。 我在糾正錯誤! – pygabriel 2010-08-13 11:40:22