我有一个非常简单的 Common Lisp 问题:从字符串列表中删除重复项的惯用方法是什么?
remove-duplicates
正如我对数字的期望,但不适用于字符串:
* (remove-duplicates '(1 2 2 3))
(1 2 3)
* (remove-duplicates '("one" "two" "two" "three"))
("one" "two" "two" "three")
我猜字符串在某种程度上不相等,很可能是因为尽管“foo”和“foo”表面上相同,但它们实际上是指向内存中不同结构的指针。我想我在这里的期望可能只是C宿醉。
您必须告诉remove-duplicates 它应该如何比较这些值。默认情况下,它使用eql
,这对于字符串来说是不够的。通过:test
函数如下:
(remove-duplicates your-sequence :test #'equal).
(编辑以解决评论中的问题):作为替代方案equal
,你可以使用string=
在这个例子中。这个谓词(在某种程度上)不如equal
它可能(可能,可能,可能,最终......)因此更快。真正的好处可能是string=
如果您传递了错误的值,可以告诉您:
(equal 1 "foo")
愉快地收获nil
, 然而
(string= 1 "foo")
gives a type-error
健康)状况。但请注意,
(string= "FOO" :FOO)
是完全明确定义的(string=
及其朋友是根据“字符串指示符”而不是字符串来定义的),因此类型安全在这里只能进行到此为止。
标准eql
另一方面,谓词几乎从来都不是比较字符串的正确方法。如果您熟悉 Java 语言,请考虑eql
作为使用==
while equal
(or string=
等)调用equals(Object)
方法。尽管eql
进行某种类型内省(而不是eq
,但没有),对于大多数(非数字)lisp 类型,eql
归结为类似指针比较的东西,如果您想根据值实际包含的内容而不是仅仅根据它们在内存中的位置来区分值,那么这是不够的。
对于更Pythonic倾向的人来说,eq
(and eql
对于非数字类型)更像是is
运算符,而equal
更像是==
哪个调用__eq__
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)