我有一个简单的Common Lisp问题:从字符串列表中删除重复项的惯用方法是什么?
remove-duplicates 像我期望的数字一样工作,但不是字符串:
* (remove-duplicates '(1 2 2 3))
(1 2 3)
* (remove-duplicates '("one" "two" "two" "three"))
("one" "two" "two" "three")
Run Code Online (Sandbox Code Playgroud)
我猜这里有一些字符串不相等的感觉,很可能因为虽然"foo"和"foo"显然是相同的,但它们实际上是指向内存中不同结构的指针.我想我的期望可能只是一个C宿醉.
Dir*_*irk 17
你必须告诉remove-duplicatelicates应该如何比较这些值.默认情况下,它使用eql,这对于字符串来说是不够的.传递:test函数如下:
(remove-duplicates your-sequence :test #'equal).
Run Code Online (Sandbox Code Playgroud)
(编辑以解决评论中的问题):作为替代方案equal,您可以string=在此示例中使用.这个谓词(在某种程度上)不那么通用equal,它可能(可能,可能,最终......)因此更快.string=如果传递错误的值,可能会告诉您一个真正的好处:
(equal 1 "foo")
Run Code Online (Sandbox Code Playgroud)
愉快地收益nil,而
(string= 1 "foo")
Run Code Online (Sandbox Code Playgroud)
给出一个type-error条件.但请注意
(string= "FOO" :FOO)
Run Code Online (Sandbox Code Playgroud)
完全定义良好(string=其朋友的定义是"字符串指示符"而不是字符串),所以类型安全只会到这里.
eql另一方面,标准谓词几乎不是比较字符串的正确方法.如果您熟悉Java语言,请考虑eql使用==while equal(或string=等)调用equals(Object)方法.虽然对于大多数(非数字)lisp类型,eql某些类型的内省(相反eq,但没有),可eql归结为像指针比较这样的东西,这是不够的,如果你想根据它们实际的区别来区分值包含,而不仅仅是它们所在的记忆位置.
对于更多Pythonic倾斜,eq(和eql非数字类型)更像是is 运算符,而equal更像==是调用__eq__.
| 归档时间: |
|
| 查看次数: |
4768 次 |
| 最近记录: |