Mir*_*lov 24 lisp associative-array elisp
我在emacs lisp中有一个列表:
(setq a1
'((:k1 . 1)
(:k2 . 2)
(:k3 . 3)))
Run Code Online (Sandbox Code Playgroud)
我想将值改为:k1到10,就像(:k1 . 10).我怎么做?
我试过(setf (assoc :k1 a1) '(:k1 . 10))- 它没用.
krz*_*z00 20
使用alist,你通常会在旧的前面添加一个新的缺点来"遮蔽"旧值,如下所示:
(add-to-list 'a1 '(:k1 10))
Run Code Online (Sandbox Code Playgroud)
这样做之后(assoc :k1 a1)将返回10.
如果您想"撤消"您的更改,请assoc再次返回旧值,请使用以下代码:
(setq a1 (delq (assoc :k1 a1) a1))
Run Code Online (Sandbox Code Playgroud)
这将删除FIRST匹配:k1的a1.
从Emacs 25.1开始,alist-get是一个地方表单,您可以这样做:
(setf (alist-get :k1 a1) 10)
Run Code Online (Sandbox Code Playgroud)
该setf宏不知道assoc,但你仍然可以使用这种方法在一个稍微手动方式:
(let ((item (assoc :k1 a1)))
(setf (car item) :k1)
(setf (cdr item) 10))
Run Code Online (Sandbox Code Playgroud)
如果只需要为给定的汽车设置cdr(而不是替换两者),那么我们可以将其简化为:
(setf (cdr (assoc :k1 a1)) 10)
Run Code Online (Sandbox Code Playgroud)
小智 5
这个更短更简单的版本对我来说适用于 Emacs Lisp (MAC Lisp):
(setcdr (assoc :k1 a1) 10)
Run Code Online (Sandbox Code Playgroud)
或者,如果您碰巧使用的是 Common Lisp:
(rplacd (assoc :k1 a1) 10)
Run Code Online (Sandbox Code Playgroud)
(请注意, setcdr 和 rplad 在涉及返回哪个值时的行为可能略有不同。)