Common lisp Common Lisp-是否有内置函数按键过滤plist?

Common lisp Common Lisp-是否有内置函数按键过滤plist?,common-lisp,plist,Common Lisp,Plist,我正在寻找一个内置功能,如以下键的pfilter: 按键过滤“:a:b”:c 10:b 20:a 4 ;; => :B 20:A 4 其代码非常简单: 按键plist解除过滤 列表->PList->PList 返回一个新的plist,其中只包含与给定 钥匙。 通过“cddr”在plist上为k v循环 当成员k键时:测试“相等” 附加列表k v CL是否有类似于上述功能的内置功能 注:有一个非常接近的功能:从plist中删除。是一个构建块: (defun keep-properties (pli

我正在寻找一个内置功能,如以下键的pfilter:

按键过滤“:a:b”:c 10:b 20:a 4 ;; => :B 20:A 4 其代码非常简单:

按键plist解除过滤 列表->PList->PList 返回一个新的plist,其中只包含与给定 钥匙。 通过“cddr”在plist上为k v循环 当成员k键时:测试“相等” 附加列表k v CL是否有类似于上述功能的内置功能

注:有一个非常接近的功能:从plist中删除。

是一个构建块:

(defun keep-properties (plist indicator-list &aux k v)
  "Keeps all property list entries for a given indicator-list."
  (loop do (setf (values k v plist)
                 (get-properties plist indicator-list))
        while plist
        collect k collect v
        do (pop plist) (pop plist)))
请注意,收集两次比在循环中追加/列出更好。

是一个构建块:

(defun keep-properties (plist indicator-list &aux k v)
  "Keeps all property list entries for a given indicator-list."
  (loop do (setf (values k v plist)
                 (get-properties plist indicator-list))
        while plist
        collect k collect v
        do (pop plist) (pop plist)))

请注意,收集两次要比在循环中追加/列出更好。

没有函数可以执行此操作,而这不是通常想要执行的操作

有一个宏remf,它在某个地方从plist中删除一个键

实现这一目标的另一种方法是:

(destructuring-bind (&key (a nil ap) (b nil bp) &allow-other-keys) plist
  (append (if ap (list :a a)) (if bp (list :b b))))
但请注意,只有当您已经知道要保留哪些关键点,并且这不会保留plist中的顺序,也不会保留重复的关键点(即,如果plist包含该关键点:多次,结果将只包含一次)时,此方法才有效


您可以使用普通符号键的普通lambda列表语法对非关键字键进行修改。

没有函数可以执行此操作,这不是通常想要执行的操作

有一个宏remf,它在某个地方从plist中删除一个键

实现这一目标的另一种方法是:

(destructuring-bind (&key (a nil ap) (b nil bp) &allow-other-keys) plist
  (append (if ap (list :a a)) (if bp (list :b b))))
但请注意,只有当您已经知道要保留哪些关键点,并且这不会保留plist中的顺序,也不会保留重复的关键点(即,如果plist包含该关键点:多次,结果将只包含一次)时,此方法才有效


您可以使用普通符号键的普通lambda list语法对非关键字键进行修改。

在您的函数中,如果您的键将成为符号,您可能应该通过eq或eql而不是equal进行测试。或者至少有一个:test参数,默认为eql。您还可以更改附加到nconc,因为列表是新的,甚至可以将其更改为collect k和collect v,因为它们可能会执行得更好。最后,如果你想用pLIST来做这些类似地图的事情,你可能应该考虑使用可以更快或更普通的哈希表,而普通列表运算符则更适用。我认为在比较符号时,均等会回到EQ。它只不过是将两个事情与EQ编译成一个指令,而用equal几乎可以和eq一样快,但对于不必按类型分派且可能在函数中递归的对象,equal要慢得多。如果您的键是符号,您可能应该使用eq或eql而不是equal进行测试。或者至少有一个:test参数,默认为eql。您还可以更改附加到nconc,因为列表是新的,甚至可以将其更改为collect k和collect v,因为它们可能会执行得更好。最后,如果你想用pLIST来做这些类似地图的事情,你可能应该考虑使用可以更快或更普通的哈希表,而普通列表运算符则更适用。我认为在比较符号时,均等会回到EQ。它只不过是将两个事情与EQ编译成一个指令,而用equal几乎可以和eq一样快,但对于不需要在类型上进行调度且可能递归的事物,equal要慢得多@rainer joswig!很高兴两次了解get属性和收集语法。谢谢@rainer joswig!很高兴了解get属性和收集两次的语法。谢谢@dan robertson!我的案例非常简单,我没有考虑过应用解构绑定。好主意谢谢@dan robertson!我的案例非常简单,我没有考虑过应用解构绑定。好主意