Lisp 修改plist内部列表?
我有一个列表,其中包括Lisp 修改plist内部列表?,lisp,common-lisp,sbcl,Lisp,Common Lisp,Sbcl,我有一个列表,其中包括 '((:atom Toddler :visited nil :on-clauses (0 1)) (:atom Child :visited nil :on-clauses 1)) 如何更改给定的:atom上的:onclauses属性?我想更新此属性,例如制作第二个plist(:atom Child:visted nil:on子句(12))(仅添加新值,从不删除旧值) 我所能做的就是使用 (remove-if-not #'(lambda(record)
'((:atom Toddler :visited nil :on-clauses (0 1))
(:atom Child :visited nil :on-clauses 1))
如何更改给定的:atom
上的:onclauses
属性?我想更新此属性,例如制作第二个plist(:atom Child:visted nil:on子句(12))
(仅添加新值,从不删除旧值)
我所能做的就是使用
(remove-if-not #'(lambda(record)
(equal (getf record :atom) atom))
*ATOMS*)
要获得初始值,请更新它,然后使用其类似项获得一个没有此值的列表,并将两者附加在一起,但这可能是非常不够的(我知道过早优化是不好的,但我正在学习LISP,希望知道如何正确操作!)使用特定的:atom
查找plist,然后从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*
成为将原子映射到属性列表的列表可能更简单。用于查找具有特定:atom
的plist,然后从该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))))
使原子*成为一个将原子映射到属性列表的列表可能更简单。这三个函数似乎起到了作用,因为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))
这三个函数似乎起到了作用,因为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))
嘿@Barmar,谢谢你的回答!这似乎不是我想要的,我一定写得很糟糕。我发现我这样做其实是太过分了;由于plists被破坏性地改变,只要
setf
ing我从我所写的内容中得到的列表,就会使*atoms*
列表成为我想要的方式!我在你的代码中看到了如果不删除就删除,所以我以为你想删除该属性。我已经更新了我的答案。您的版本不一定有效,因为getf的setf可以简单地分配给局部变量atomo
,而无需修改全局变量*atoms*
中的列表。嘿@Barmar,谢谢您的回答!这似乎不是我想要的,我一定写得很糟糕。我发现我这样做其实是太过分了;由于plists被破坏性地改变,只要setf
ing我从我所写的内容中得到的列表,就会使*atoms*
列表成为我想要的方式!我在你的代码中看到了如果不删除就删除,所以我以为你想删除该属性。我已经更新了我的答案。您的版本不一定有效,因为getf的setf
可以简单地分配给局部变量atomo
,而无需修改全局变量*atoms*
中的列表。请注意,您不应该修改引用的文本数据。影响尚未定义。要么使用非破坏性操作,要么复制之前的树。你有什么参考资料我可以读到这个@RainerJoswig吗?我是LISP的新手。请注意,您不应该修改引用的文字数据。影响尚未定义。要么使用非破坏性操作,要么复制之前的树。你有什么参考资料我可以读到这个@RainerJoswig吗?我对LISP相当陌生。您可以使用(find-atom*atoms*:key(lambda(record)(getf-record:atom))
而不是find-atom
。另外,(setf(getf…(cons-ix…)
可以简化为(push-ix(getf…)
,这使得获取索引的功能变得不必要。感谢您的提示,@jkiiski!我不知道我可以用那种方式找到。。。虽然我不确定我是否理解它是如何工作的。它使用atom将lambda函数应用于atoms中的每个列表,并返回具有非空值的列表?至于你的第二个建议,我不确定它是否符合我的要求,我会尽快尝试!FIND
对*ATOMS*
中的每个对象调用键函数(此处返回:ATOM
属性的值),并将返回值与第一个参数(ATOM
)进行比较。返回键为EQL
到ATOM
的第一个对象。太好了,谢谢@jkiiski!我现在明白了。至于第二个建议,我似乎无法做到这一点:(push 1(getf'(:atom Child:on子句(02)):on子句))
。这就是您的意思吗?尝试将(setf…
表单替换为(push ix(getf atomo:on子句))
。您可以使用(find atom*atoms*:key(lambda(record)(getf record:atom))
而不是find-atom
。另外,(setf(getf…(cons-ix…)
可以简化为(push-ix(getf…)
,这使得获取索引的功能变得不必要。感谢您的提示,@jkiiski!我不知道我可以用那种方式找到。。。虽然我不确定我是否理解它是如何工作的。它使用atom将lambda函数应用于atoms中的每个列表,并返回具有非空值的列表?至于你的第二个建议,我不确定它是否符合我的要求,我会尽快尝试!FIND
对*ATOMS*
中的每个对象调用键函数(此处返回:ATOM
属性的值),并将返回值与第一个参数(ATOM
)进行比较。返回键为EQL
到ATOM
的第一个对象。太好了,谢谢@jkiiski!我现在明白了。至于第二个建议,我似乎无法做到这一点:(push 1(getf'(:atom Child:on子句(02)):on子句))
。这就是你的意思吗?试着用(push ix(getf atomo:on子句))
替换(setf…
表单。