我在emacs lisp中有一个alist:
(setq a1
'((:k1 . 1)
(:k2 . 2)
(:k3 . 3)))
我希望将值k1更改为10,如(:k1 . 10)
。我该怎么做?
我尝试了(setf (assoc :k1 a1) '(:k1 . 10))
- 它没有用。
答案 0 :(得分:20)
使用alists,你通常会在旧的前面添加一个新的缺点来“遮蔽”旧值,如下所示:
(add-to-list 'a1 '(:k1 10))
执行此操作后,(assoc :k1 a1)
将返回10.
如果您要“撤消”更改,assoc
再次返回旧值,请使用以下代码:
(setq a1 (delq (assoc :k1 a1) a1))
这将从:k1
移除a1
的第一次匹配。
答案 1 :(得分:7)
从Emacs 25.1开始,alist-get
是一个地方表单,您可以这样做:
(setf (alist-get :k1 a1) 10)
答案 2 :(得分:5)
setf
宏不了解assoc
,但您仍然可以稍微以手动方式使用该方法:
(let ((item (assoc :k1 a1)))
(setf (car item) :k1)
(setf (cdr item) 10))
如果只需要为给定的汽车设置cdr(而不是替换两者),那么我们可以将其简化为:
(setf (cdr (assoc :k1 a1)) 10)
答案 3 :(得分:4)
这个更短更简单的版本适用于我的Emacs Lisp(MAC Lisp):
(setcdr (assoc :k1 a1) 10)
或者,如果你碰巧使用Common Lisp:
(rplacd (assoc :k1 a1) 10)
(请注意,setcdr和rplacd在返回哪个值时可能会略有不同。)
答案 4 :(得分:1)
assq-delete-all
:
(setq sql-product-alist
(cons '(ms-tsql :server ....)
(assq-delete-all 'ms-tsql sql-product-alist)))
答案 5 :(得分:1)
这是基于gavenkoa建议的功能 -
(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))