作为 CL 的新手,我经常使用简单的算法。例如,我尝试实现一个删除列表中所有唯一元素的函数。
(1 2 2 3 3 4 5 3) -> (2 2 3 3 3)
第一次尝试导致此代码:
(defun remove-unique (items)
(let ((duplicates (set-difference items (remove-duplicates items :test #'equal))))
(append duplicates (remove-duplicates duplicates :test #'equal))))
这对于字符串可以正常工作,但对于数字总是返回NIL
。阅读更多有关 set-difference
的内容,我了解到它根本不适用于重复的填充列表,它只是在我的情况下以某种方式工作,所以我放弃了该方法,因为它不可移植并且继续前进。
另一个尝试是:
(defun remove-unique (items)
(loop for item in items
when (member item (cdr (member item items)))
collect item))
对于数字来说这可以正常工作,但对于字符串则返回NIL
。
显然,我不明白字符串和数字之间存在核心区别。为什么 member
和 set-difference
等列表处理函数对它们的工作方式不同?
最佳答案
数字、字符和字符串的相等比较确实是不同的。 Equal,您应该谨慎使用,因为它更昂贵,它具有结构相等性(因此它会落在某些对象上)。 eq 实现对象相等。 eql 在大多数情况下都执行对象相等,除了数字(它们检查类型和值)和字符(它们检查“值”)之外
关于string - Common Lisp 中字符串和数字的核心区别是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18205073/