【问题标题】:Modifying a property list修改属性列表
【发布时间】:2015-09-13 17:03:40
【问题描述】:

我有一个property list

(setf *star* '(:points 5))

我想修改这个 plist。有时更好的选择是进行突变,有时更好的选择是使用不可变更新。

如何使用mutation修改plist?

(mutate *star* :points 6)
*star* ; '(:points 6)

以及如何使用不可变更新修改 plist?

(update *star* :points 6) ; '(:points 6)
*star*                    ; '(:points 5)

【问题讨论】:

标签: common-lisp property-list


【解决方案1】:

您正在寻找的是getf,也许是get-properties。 要非破坏性地修改 plist,请使用 list*:

(setq *star* (list* :points 6 *star*))

如果你的 plist 是associated with a symbol,你应该使用getremprop

注意:使用关联列表(参见 assocacons)是一个更好的主意,因为它们更灵活(例如,使用 alist 将多个对象与键关联起来更容易切换)。

【讨论】:

    【解决方案2】:

    要改变 plist,只需使用 setf:

    (setf (getf *star* :points) 59)
    

    要进行非可变更新,在原始值不受干扰的情况下,您可以执行以下操作:

    (defun update-plist (plist indicator new-value)
        (let ((other-properties nil))
          (loop while plist
                for property = (pop plist)
                for value = (pop plist)
                when (eq property indicator)
                do (return-from update-plist (list* property new-value
                                                    (append other-properties plist)))
                else do (push value other-properties)
                        (push property other-properties))
          (list* indicator new-value other-properties)))
    

    它与您的示例不同:

    *star* ;; (:points 6 :color :green)
    (update-plist *star* :points 5) ;; (:points 5 :color :green)
    *star* ;; (:points 6 :color :green) -- Doesn't change.
    

    【讨论】:

    • 这对我更改 org-format-latex-options 中的属性值很有用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 1970-01-01
    相关资源
    最近更新 更多