Lisp 更新列表
Lisp update list
嗨,我是 AutoCad lisp 的新手,我想通过一些简单的例程来稍微加快我的工作,但我碰壁了,无法解决这个问题,我有一个强大的填充物一个简单的解决方案。所以...
我创建了一个名为 "koord":
的列表
(setq koord (list (cons "1" "10,10,10")))
结果是点对:("1" . "10,10,10")
然后我添加到这个列表中,例如:
(setq koord (append koord (list (cons "2" "20,20,20"))))
(setq koord (append koord (list (cons "3" "30,30,30"))))
现在结果是:("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30")
现在我想更新第二个点对,让我的列表看起来像这样:
("1" . "10,10,10") ("2" . "60,60,60") ("3" . "30,30,30")
但我不知道如何......如果我这样追加
(setq koord (append koord (list (cons "2" "60,60,60"))))
比我得到的结果:
("1" . "10,10,10") ("2" . "20,20,20") ("2" . "60,60,60") ("3" . "30,30,30")
如果我知道如何找回这个就不会太糟糕 ("2" . "60,60,60")
如果我尝试
(assoc "2" koord)
它返回第一次出现,即 ("2" . "20,20,20")
那么,有没有办法不添加而是更新点对中的值,或者检索附加的最后一个 - 而不是第一个?
如果你想更新记录,你可以这样做:
(def alist-update (alist key value)
"Update the value of a key or add a cell."
(let ((cell (assoc key alist)))
(if cell
(setf (cdr cell) value)
(acons key value alist))))
(setq alist (alist-update () 1 "a"))
(assoc 1 alist)
==> (1 . "a")
(setq alist (alist-update alist 1 "b"))
(assoc 1 alist)
==> (1 . "b")
虽然您使用的是 AutoLisp 而不是 Common Lisp(请注意手册中的 CL assoc
uses eql
for comparison by default and would thus return nil
for (assoc "1" ...)
) or Emacs Lisp, I still suggest that you look through the Association Lists。
鉴于您的点对列表:
_$ (setq koord '(("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30")))
(("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30"))
以下将用第二项替换新项:
_$ (subst '("2" . "60,60,60") (assoc "2" koord) koord)
(("1" . "10,10,10") ("2" . "60,60,60") ("3" . "30,30,30"))
但是请注意,这将替换所有出现的原始项目,例如:
_$ (setq koord '(("2" . "20,20,20") ("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30") ("2" . "20,20,20")))
(("2" . "20,20,20") ("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30") ("2" . "20,20,20"))
_$ (subst '("2" . "60,60,60") (assoc "2" koord) koord)
(("2" . "60,60,60") ("1" . "10,10,10") ("2" . "60,60,60") ("3" . "30,30,30") ("2" . "60,60,60"))
嗨,我是 AutoCad lisp 的新手,我想通过一些简单的例程来稍微加快我的工作,但我碰壁了,无法解决这个问题,我有一个强大的填充物一个简单的解决方案。所以...
我创建了一个名为 "koord":
的列表(setq koord (list (cons "1" "10,10,10")))
结果是点对:("1" . "10,10,10")
然后我添加到这个列表中,例如:
(setq koord (append koord (list (cons "2" "20,20,20"))))
(setq koord (append koord (list (cons "3" "30,30,30"))))
现在结果是:("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30")
现在我想更新第二个点对,让我的列表看起来像这样:
("1" . "10,10,10") ("2" . "60,60,60") ("3" . "30,30,30")
但我不知道如何......如果我这样追加
(setq koord (append koord (list (cons "2" "60,60,60"))))
比我得到的结果:
("1" . "10,10,10") ("2" . "20,20,20") ("2" . "60,60,60") ("3" . "30,30,30")
如果我知道如何找回这个就不会太糟糕 ("2" . "60,60,60")
如果我尝试
(assoc "2" koord)
它返回第一次出现,即 ("2" . "20,20,20")
那么,有没有办法不添加而是更新点对中的值,或者检索附加的最后一个 - 而不是第一个?
如果你想更新记录,你可以这样做:
(def alist-update (alist key value)
"Update the value of a key or add a cell."
(let ((cell (assoc key alist)))
(if cell
(setf (cdr cell) value)
(acons key value alist))))
(setq alist (alist-update () 1 "a"))
(assoc 1 alist)
==> (1 . "a")
(setq alist (alist-update alist 1 "b"))
(assoc 1 alist)
==> (1 . "b")
虽然您使用的是 AutoLisp 而不是 Common Lisp(请注意手册中的 CL assoc
uses eql
for comparison by default and would thus return nil
for (assoc "1" ...)
) or Emacs Lisp, I still suggest that you look through the Association Lists。
鉴于您的点对列表:
_$ (setq koord '(("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30")))
(("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30"))
以下将用第二项替换新项:
_$ (subst '("2" . "60,60,60") (assoc "2" koord) koord)
(("1" . "10,10,10") ("2" . "60,60,60") ("3" . "30,30,30"))
但是请注意,这将替换所有出现的原始项目,例如:
_$ (setq koord '(("2" . "20,20,20") ("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30") ("2" . "20,20,20")))
(("2" . "20,20,20") ("1" . "10,10,10") ("2" . "20,20,20") ("3" . "30,30,30") ("2" . "20,20,20"))
_$ (subst '("2" . "60,60,60") (assoc "2" koord) koord)
(("2" . "60,60,60") ("1" . "10,10,10") ("2" . "60,60,60") ("3" . "30,30,30") ("2" . "60,60,60"))