我在 emacs lisp 中有一个 alist,例如:
(setq a1
'((:k1 . 1)
(:k2 . 2)
(:k3 . 3)))
我想将:k1 的值更改为 10,例如(:k1 . 10)
。我怎么做?
我试过(setf (assoc :k1 a1) '(:k1 . 10))
了 - 它没有用。
我在 emacs lisp 中有一个 alist,例如:
(setq a1
'((:k1 . 1)
(:k2 . 2)
(:k3 . 3)))
我想将:k1 的值更改为 10,例如(:k1 . 10)
。我怎么做?
我试过(setf (assoc :k1 a1) '(:k1 . 10))
了 - 它没有用。
使用 alists,您通常会在旧的 cons 前面添加一个新的 cons 以“遮蔽”旧值,如下所示:
(add-to-list 'a1 '(:k1 10))
执行此操作(assoc :k1 a1)
后将返回 10。
如果您想“撤消”您的更改以便assoc
再次返回您的旧值,请使用以下代码:
(setq a1 (delq (assoc :k1 a1) a1))
这将删除 from 的第一个匹配项。:k1
a1
从 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))
如果只需要为给定汽车设置 cdr(而不是同时替换两者),那么我们可以将其简化为:
(setf (cdr (assoc :k1 a1)) 10)
这个更短更简单的版本适用于我的 Emacs Lisp (MAC Lisp):
(setcdr (assoc :k1 a1) 10)
或者,如果您碰巧使用的是 Common Lisp:
(rplacd (assoc :k1 a1) 10)
(请注意,当涉及到返回的值时,setcdr 和 rplacd 的行为可能略有不同。)
怎么样assq-delete-all
:
(setq sql-product-alist
(cons '(ms-tsql :server ....)
(assq-delete-all 'ms-tsql sql-product-alist)))
这是基于 givenkoa 建议的功能-
(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))