2010-08-13 20 views
5

ben başka bir deyişle, bir dernek listeden bir öğe "pop" için bir yol, bir "yıkıcı" assoc Arıyorum:(elisp)

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

Are elisp kablo demetinde herhangi bir işlev var mı? Bir symilar işlevsellik elde etmenin en zarif yolu nedir? ("Yan etkisi" bu tür mümkün olsa bile, iyi bir uygulamadır bu konuda emin değilim!)

cevap

3

Orada farkındayım böyle yerleşik operatör, ama oldukça hızlı bir şekilde bu işlevselliği alabilirsiniz düşünmek:

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

assq-delete-all istediğini yakındır. Nesne kimliği (eq) öğelerine, değer eşitliği ile değil (equal). Sadece eşleşen değil, tüm eşleşen öğeleri kaldırır. Değiştirilen listeyi döndürür. İstediğiniz şeyi yapmak için bu işlevin kodunu uyarlayabilirsiniz. (Ama assq-delete-all tek ihtiyacınız yok, bir döngü içinde assoc-pop arayacağını ve tüm tuşlar semboller ise.)

Not "a" ve 'a tamamen farklı nesneler olduklarını: İlk bir dizidir ikinci bir sembol. Yani ikinci satırınız (assoc-pop 'a alist) olmalıdır.

Ama (assoc-pop makro değilse) o listedeki ilk öğesini kaldırma aciz olduğu için aslında, çağrı (assoc-pop 'a alist), çalışamaz

. Sen argüman olarak bir sembol alır ve add-to-list modelini takiben simgesinin değerini olduğu listeyi değiştiren bir işlev yapabilirsiniz. Bunu (assoc-pop 'a 'alist) olarak adlandırırdınız.

+0

sembollerle ilgili noktası için de teşekkür ederim, ben yeniyim lisp ve ben henüz sembol/liste/other_things şeyleri kavramadım. ben hata düzeltme ediyorum! – pygabriel

İlgili konular