การเปิดองค์ประกอบจากรายการการเชื่อมโยงด้วยเสียงกระเพื่อม (elisp)

ฉันกำลังค้นหาวิธี "ป๊อป" องค์ประกอบจากรายการการเชื่อมโยง หรืออีกนัยหนึ่งคือ สมาคม "ทำลายล้าง":

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

มีฟังก์ชั่นใดบ้างในชุดสายรัด elisp? วิธีที่หรูหราที่สุดในการรับฟังก์ชั่นที่คล้ายกันคืออะไร? (ไม่แน่ใจว่า "ผลข้างเคียง" ประเภทนี้เป็นวิธีปฏิบัติที่ดี แม้ว่าจะเป็นไปได้ก็ตาม!)


person pygabriel    schedule 13.08.2010    source แหล่งที่มา


คำตอบ (2)


ไม่มีโอเปอเรเตอร์ในตัวที่ฉันทราบ แต่ฉันคิดว่าคุณสามารถใช้ฟังก์ชันนี้ได้อย่างรวดเร็ว:

(defmacro assoc-pop (key alist)
  `(let ((result (assoc ,key ,alist)))
     (setq ,alist (delete result ,alist))
     result))
person Svante    schedule 13.08.2010

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)

person Gilles 'SO- stop being evil'    schedule 13.08.2010
comment
ขอบคุณสำหรับประเด็นเกี่ยวกับสัญลักษณ์ ฉันยังใหม่กับเสียงกระเพื่อมและฉันยังไม่เข้าใจสัญลักษณ์/รายการ/สิ่งอื่นๆ ฉันกำลังแก้ไขข้อผิดพลาด! - person pygabriel; 13.08.2010