Elisp: How to delete an element from an association list with string key
If you know there can only be a single matching entry in your list, you can also use the following form:
(setq al (delq (assoc <string> al) al)
Notice that the setq
(which was missing from your sample code) is very important for `delete' operations on lists, otherwise the operation fails when the deleted element happens to be the first on the list.
The q
in assq
traditionally means eq
equality is used for the objects.
In other words, assq
is an eq
flavored assoc
.
Strings don't follow eq
equality. Two strings which are equivalent character sequences might not be eq
. The assoc
in Emacs Lisp uses equal
equality which works with strings.
So what you need here is an assoc-delete-all
for your equal
-based association list, but that function doesn't exist.
All I can find when I search for assoc-delete-all
is this mailing list thread:
http://lists.gnu.org/archive/html/emacs-devel/2005-07/msg00169.html
Roll your own. It's fairly trivial: you march down the list, and collect all those entries into a new list whose car
does not match the given key under equal
.
One useful thing to look at might be the Common Lisp compatibility library. http://www.gnu.org/software/emacs/manual/html_node/cl/index.html
There are some useful functions there, like remove*
, with which you can delete from a list with a custom predicate function for testing the elements. With that you can do something like this:
;; remove "a" from al, using equal as the test, applied to the car of each element
(setq al (remove* "a" al :test 'equal :key 'car))
The destructive variant is delete*
.