修改列表中的plist?

时间:2017-06-05 19:42:07

标签: lisp common-lisp sbcl

我有一个列表,例如

'((: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和想知道如何正确地做事!)

2 个答案:

答案 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))