2017-06-05 23 views
0

我的Plist如修改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*) 

获取初始值,更新它,然后用其模拟得到没有该值的列表从头开始创建一个新的列表,并追加两者一起,但是这可能是非常inneficient(我知道过早optimatization是不好的,但我学习LISP,想知道如何做正确的事!)

+2

请注意,您不应修改文字引用数据。效果不明确。请使用非破坏性操作或复制之前的树。 –

+0

你有一些我可以阅读关于@RainerJoswig的参考吗?我相当新的LISP .. –

回答

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可能会更简单。

+0

嘿@Barmar,谢谢你的答案!这似乎没有做到我想要的,我一定写得很糟糕。我发现我做这件事的方式实际上是过度的;因为plists被破坏性地改变了,只是'''''''''''''''''''''''' –

+0

我在代码中看到了'remove-if-not',所以我以为你想要删除这个属性。 – Barmar

+0

我已经更新了我的答案。你的版本不一定会工作,因为'setf of getf'可以简单地分配给局部变量'atomo',而不用修改全局变量'* atoms *'中的列表。 – Barmar

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)) 
+1

你可以使用'(find atom * atoms *:key(lambda(record)(getf record:atom)))'而不是你的'FIND-ATOM'。另外''(setf(getf ...)(cons ix ...))'可以简化为'(push ix(getf ...))',因此不需要GET-INDICES函数。 – jkiiski

+0

感谢提示,@ jkiiski!我不知道我可以用这种方式找到...虽然我不确定我是否理解它是如何工作的。它将使用原子的lambda函数应用于* atoms *中的每个列表,并返回具有非空值的列表? 至于你的第二个建议,我不确定它做了我想要的,我会尽快尝试! –

+0

'FIND'调用'* ATOMS *'中每个对象的键函数(这里返回':ATOM'属性的值),并将返回值与第一个参数('ATOM')进行比较。返回键“EQL”到“ATOM”的第一个对象。 – jkiiski