我有一个诸如
之类的plist列表'((:atom Toddler :visited nil :on-clauses (0 1))
(:atom Child :visited nil :on-clauses 1))
如何更改给定:atom
上的:onclauses
属性?我想更新此属性,例如制作第二个PLIST (:atom Child :visited nil :on-clauses (1 2))
(仅添加新值,切勿删除旧值(。
我能做的最好的是使用
从头开始创建一个新列表(remove-if-not #'(lambda(record)
(equal (getf record :atom) atom))
*ATOMS*)
要获得初始值,对其进行更新,然后使用其模拟获取一个没有此值的列表,并将两者都添加在一起,但这可能是非常无缺的(我知道过早的优化是不好的,但是我正在学习LISP和想知道如何正确地做事!(
使用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可能更简单的。
这三个函数似乎可以解决问题,因为plist被破坏性修改。
(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))