Memunculkan elemen dari daftar asosiasi di cadel (elisp)

Saya sedang mencari cara untuk "memunculkan" elemen dari daftar asosiasi, dengan kata lain asosiasi "destruktif":

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

Apakah ada fungsi di elisp harness? Apa cara paling elegan untuk mendapatkan fungsi serupa? (tidak yakin bahwa "efek samping" semacam ini adalah praktik yang baik, meskipun mungkin!)


person pygabriel    schedule 13.08.2010    source sumber


Jawaban (2)


Tidak ada operator bawaan yang saya ketahui, namun menurut saya Anda bisa mendapatkan fungsi ini dengan cukup cepat:

(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 mendekati apa yang Anda inginkan. Ia mencari elemen berdasarkan identitas objek (eq), bukan berdasarkan persamaan nilai (equal). Ini menghapus semua elemen yang cocok, bukan hanya yang pertama. Ini mengembalikan daftar yang dimodifikasi. Anda dapat mengadaptasi kode fungsi ini untuk melakukan apa yang Anda inginkan. (Tetapi jika Anda akan memanggil assoc-pop dalam satu lingkaran, dan semua kunci Anda adalah simbol, assq-delete-all akan melakukan semua yang Anda perlukan.)

Perhatikan bahwa "a" dan 'a adalah objek yang sangat berbeda: yang pertama adalah string, yang kedua adalah simbol. Jadi baris kedua Anda seharusnya (assoc-pop 'a alist).

Namun kenyataannya, panggilan (assoc-pop 'a alist) tidak dapat berfungsi (kecuali assoc-pop adalah makro), karena panggilan tersebut tidak mampu menghapus elemen pertama dalam daftar. Anda dapat membuat fungsi yang menggunakan simbol sebagai argumen dan mengubah daftar yang merupakan nilai simbol, mengikuti model add-to-list. Anda akan menyebutnya sebagai (assoc-pop 'a 'alist).

person Gilles 'SO- stop being evil'    schedule 13.08.2010
comment
Terima kasih juga atas poin tentang simbol, saya baru mengenal cadel dan saya belum memahami hal-hal tentang simbol/daftar/lainnya. Saya sedang memperbaiki kesalahannya! - person pygabriel; 13.08.2010