【发布时间】:2017-11-26 15:25:32
【问题描述】:
我正在寻找像下面的pfilter-by-keys 这样的内置函数:
(pfilter-by-keys '(:a :b) '(:c 10 :b 20 :a 4))
;; => (:B 20 :A 4)
它的代码很简单:
(defun pfilter-by-keys (keys plist)
"List -> PList -> PList
Returns a new plist with only the keys/values correspondent to the given
keys."
(loop for (k v) on plist by #'cddr
when (member k keys :test #'equal)
append (list k v)))
CL 有没有像上面那样的内置函数?
PS.:Alexandria 有一个非常接近的功能:remove-from-plist。
【问题讨论】:
-
在你的函数中,如果你的键是符号,你可能应该通过
eq或eql而不是equal进行测试。或者至少有一个默认为eql的:test参数。您还可以将append更改为nconc,因为列表是新鲜的,甚至可以将其更改为collect k and collect v,因为这些可能会表现更好。最终,如果你想用 plist 做这些类似地图的事情,你可能应该考虑使用 hashmaps(可能更快)或 alists(普通列表运算符更适用)。 -
我认为
equal在比较符号时会退回到eq(ref)。 -
它只是用
eq比较两个东西编译成一条指令,而用equal测试eq的东西几乎和eq一样快,但速度慢得多不是(必须按类型分派并可能递归)
标签: common-lisp plist