Elisp: How to delete an element from an association list with string key

后端 未结 4 1281
执念已碎
执念已碎 2021-02-07 06:54

Now this works just fine:

(setq al \'((a . \"1\") (b . \"2\")))
(assq-delete-all \'a al)

But I\'m using strings as keys in my app:



        
4条回答
  •  长发绾君心
    2021-02-07 07:09

    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*.

提交回复
热议问题