我在Emacs Lisp中有一个列表,如下所示:
(setq a1
'((:k1 . 1)
(:k2 . 2)
(:k3 . 3)))
我想将:k1的值更改为10,类似于(:k1 . 10)
。我该怎么做?
我尝试了(setf (assoc :k1 a1) '(:k1 . 10))
,但它没有起作用。
我在Emacs Lisp中有一个列表,如下所示:
(setq a1
'((:k1 . 1)
(:k2 . 2)
(:k3 . 3)))
我想将:k1的值更改为10,类似于(:k1 . 10)
。我该怎么做?
我尝试了(setf (assoc :k1 a1) '(:k1 . 10))
,但它没有起作用。
使用alist时,通常在旧值前面添加一个新的cons以“掩盖”旧值,方法如下:
(add-to-list 'a1 '(:k1 10))
执行此操作后,(assoc :k1 a1)
将返回10。
如果您想“撤销”更改以便 assoc
再次返回旧值,请使用此代码:
(setq a1 (delq (assoc :k1 a1) a1))
这将从a1
中删除:k1
的第一个匹配项。
从Emacs 25.1开始,alist-get
是一个位置表达式,因此您可以这样做:
(setf (alist-get :k1 a1) 10)
setf
宏并不知道assoc
,但您仍然可以手动使用这种方法:(let ((item (assoc :k1 a1)))
(setf (car item) :k1)
(setf (cdr item) 10))
如果只需要为给定的car设置cdr(而不是替换两者),那么我们可以简化为:
(setf (cdr (assoc :k1 a1)) 10)
这个版本对我来说很有效。
(setcdr (assoc :k1 a1) 10)
如果您恰好使用的是Common Lisp:
(rplacd (assoc :k1 a1) 10)
(defun alist-set (alist-symbol key value)
"Set KEY to VALUE in alist ALIST-SYMBOL."
(set alist-symbol
(cons (list key value)
(assq-delete-all key (eval alist-symbol)))))
使用方法 -
(let ((foo '((a 1) (b 2))))
(alist-set 'foo 'a 3)
foo) ; => ((a 3) (b 2))
assq-delete-all
:(setq sql-product-alist
(cons '(ms-tsql :server ....)
(assq-delete-all 'ms-tsql sql-product-alist)))