我有一个列表,例如
'((:atom Toddler :visited nil :on-clauses (0 1))
(:atom Child :visited nil :on-clauses 1))
如何更改给定:onclauses
的{{1}}属性?我想更新这个属性,例如制作第二个plist :atom
(仅添加新值,永不删除旧值)。
我能做的最好的事情是使用
从头创建一个新列表(:atom Child :visited nil :on-clauses (1 2))
得到初始值,更新它,然后使用它的模拟得到一个没有这个值的列表,并将它们加在一起,但这可能非常有用(我知道过早的优化是坏的,但我正在学习LISP和想知道如何正确地做事!)
答案 0 :(得分:2)
使用POSITION
查找具有特定:atom
的plist,然后REMF
以从该plist中删除该属性。
(defun update-on-clauses (atom new-on-clause)
(let ((pos (position atom *atoms*
:key #'(lambda (record) (getf record :atom)))))
(when pos
(setf (getf (nth pos *atoms*) :on-clauses) new-on-clause))))
将*ATOMS*
作为将原子映射到属性列表的alist可能更简单。
答案 1 :(得分:1)
这三个函数似乎可以解决问题,因为plists被破坏性地修改了。
(defun update-atom(atom ix)
"adds to the atom's on-clauses property another clause where it was found."
(let ((atomo (find-atom atom)))
(setf (getf atomo :on-clauses) (cons ix (get-indices atom)))))
(defun find-atom(atom) "returns the property list of a given atom"
(first (remove-if-not #'(lambda(record) (equal (getf record :atom) atom)) *ATOMS*)))
(defun get-indices(atom)
"gets indices of clauses where atom is found."
(getf (find-atom atom) :on-clauses))