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*
.
assq-delete-all
back to the variable even though it is a destructive operation:(setq al (assq-delete-all 'a al))
. What if the list becomes empty? Theal
must take on the value nil: how will that happen? Or what if you delete the first element, the head cons to whichal
initially points?al
must be updated to skip to the second cell. – Karliseseq-remove
orcl-remove(-if)
. This only returns the 'filtered' list, so to update the value you should update the original value usingsetq
(which is always recommended/safer, also when using 'destructive' operations likedelete
; at least it is like that in Common-Lisp according to Paul Graham; he mentions this in one, or multiple, of his books). – Katheleenkatherin