2017-06-05 69 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