替换elisp中关联列表中的项

替换elisp中关联列表中的项,lisp,elisp,associative-array,Lisp,Elisp,Associative Array,我在emacs lisp中有一个列表,如: (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 如果要“撤消”

我在emacs lisp中有一个列表,如:

(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))

这将从
a1
中删除
:k1
的第一个匹配项
setf
宏不知道
assoc
,但您仍然可以以稍微手动的方式使用该方法:

(let((项目(assoc:k1 a1)))
(setf(车辆项目):k1)
(setf(cdr项目)10))
如果只需要为给定的汽车设置cdr(而不是同时更换两者),那么我们可以将其简化为:

(setf(cdr(assoc:k1a1))10)

如何
全部删除

(setq sql-product-alist
      (cons '(ms-tsql :server ....)
            (assq-delete-all 'ms-tsql sql-product-alist)))

这是一个基于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))

从Emacs 25.1开始,
alist get
是一个位置表单,因此您可以执行以下操作:

(setf (alist-get :k1 a1) 10)

这个简短的版本在Emacs Lisp(MAC Lisp)中适用于我:

或者,如果您碰巧正在使用Common Lisp:

(rplacd (assoc :k1 a1) 10)

(请注意,setcdr和rplacd在返回哪个值时的行为可能略有不同。)

可能没有必要将汽车设置为:k1,因为这已经是值了。作为一般规则,将新值推送到assoc列表上可能比修改它们更好,但这一切都取决于为什么要尝试设置新值。同意,但由于我正在修改问题中的代码,这确实设置了汽车,我也将其包括在这里。当然,如果不需要设置汽车,那么代码可以简化,因此我将添加该选项。
(rplacd (assoc :k1 a1) 10)