Common Lisp:有效地附加嵌套plist

qua*_*tus 6 nested append common-lisp plist

我正在使用嵌套的plist来创建对象结构(CLOS类型),将嵌套的对象传递给它的部分.我想以迭代的方式附加嵌套的plist,但因此我想在时间和内存方面有效地做到这一点.

以下示例显示了由于一次迭代导致的增量:

'(:airframer "Boeing" :type "777" :wing-plist ((:side :left :winglet? nil)
                                                (:side :right :winglet? nil)))
Run Code Online (Sandbox Code Playgroud)

'(:airframer "Boeing" :type "777" :wing-plist ((:type :main-wing :side :left)
                                                (:type :main-wing :side :right)
                                                (:type :stabilizer :size :left)))
Run Code Online (Sandbox Code Playgroud)

我已经读过使用向量而不是列表可能会有所帮助,因为您访问元素时没有太多的惩罚:在Common Lisp中替换列表中的项目?.但是,我真的想绕过矢量的使用.

此外,我认为使用破坏性功能可以节省内存并希望计算时间.

这就是我现在解决的问题,但我觉得它不优雅高效.该功能fill用于破坏性.

(defun append-nested-plist (plist key sub-plist)
  (let* ((key-pos (position key plist)))
    (fill plist (append (getf plist key) (list sub-plist))
          :start (+ key-pos 1) :end (+ key-pos 2))))
Run Code Online (Sandbox Code Playgroud)

我期待着你的回答.

Cla*_*ley 4

这个怎么样?

(defun append-nested-plist (plist key sub-plist)
  (push-to-end sub-plist (getf plist key))
  plist)
Run Code Online (Sandbox Code Playgroud)

Push-to-end 是一个通用定义的宏,不属于 common Lisp 标准:

(defmacro push-to-end (item place)
  `(setf ,place (nconc ,place (list ,item))))
Run Code Online (Sandbox Code Playgroud)