I have an alist whose keys are strings, and I need to set the value for one of its keys. If the key is not present, I need to add it. So for example,
(alist-set "a" "bb" '(("a" . "b") ("c" . "d"))) => '(("a" . "bb") ("c" . "d"))
(alist-set "a" "bb" '(("c" . "d"))) => '(("a" . "bb") ("c" . "d"))
Introducing duplicate entries is not acceptable. Mutating the original alist is allowed.
Here are some incorrect solutions:
Using
alist-get:(setf (alist-get key alist) val)This is incorrect because
alist-getcompares keys usingeq, but string keys must be compared usingequal. I could implement a new version of thesetfaccessor foralist-getthat usesequal, but the original implementation ingv.elis 26 lines of code. That is a lot of boilerplate for this simple operation.Using
setcdrwithassoc:(setcdr (assoc key alist) val) (setf (cdr (assoc key alist)) val)This is incorrect because it fails when the key is not present in the alist to begin with.
Use the fact that earlier entries in an alist shadow later ones:
(push (cons key val) alist)This is incorrect because it introduces a duplicate entry for
keyin the alist.
Here are some questions whose answers do not answer this question: