(setq tester (list 0 1 2 3 4 5 6))
(delete-duplicates tester :key #'oddp :start 1 :end 6) => (0 4 5 6)
请问这个示例中key的含义是什么? 文档参考链接 http://clhs.lisp.se/Body/f_rm_rm.htm http://clhs.lisp.se/Body/f_rm_dup.htm
(setq tester (list 0 1 2 3 4 5 6))
(delete-duplicates tester :key #'oddp :start 1 :end 6) => (0 4 5 6)
请问这个示例中key的含义是什么? 文档参考链接 http://clhs.lisp.se/Body/f_rm_rm.htm http://clhs.lisp.se/Body/f_rm_dup.htm
去重的时候需要不断对比两个数据是否相同。有时你只需要两个数据在某一方面相同,就先用 key 函数变换一下,提取出你需要的那方面
;; 比如只要两个 pair 的 car 部分相同就等价
(setq tester '((1 2) (1 3) (0 2)))
(delete-duplicates tester :key #'car) => ((1 3) (0 2))
;; https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node144.html
;; 只要 pair 后半部分的 char 相同就等价
(remove-duplicates '((foo #\a) (bar #\%) (baz #\A))
:test #'char-equal :key #'cadr)
=> ((bar #\%) (baz #\A))
(remove-duplicates '((foo #\a) (bar #\%) (baz #\A))
:test #'char-equal :key #'cadr :from-end t)
=> ((foo #\a) (bar #\%))
但是楼主给的这个例子很有意思,依赖一些细节才输出 (0 4 5 6)
:start 1 :end 6
的 start 是包含的,end 是不包含的,
所以去重的只有 (1 2 3 4 5)
,0 和 6 是不变的
delete-duplicates 会优先保留相同元素中靠右的那个(上面例子里面的 :from-end t
会逆转这个行为)
(1 2 3 4 5)
加上 :key #'oddp
会变成 (t f t f t)
,对应位置去重 (保留最右边 f t 对应的元素),并优先保留右边就变成了 (4 5)
然后结果就是 (0 4 5 6)
这种依赖细节的东西,盲猜是学校的作业或课件什么的,藏着点东西阴一下不学的,作为例子感觉不合适。
如果没有 :start :end
列表就会变成 (0 1 2 3 4 5 6)
=> (NIL T NIL T NIL T NIL)
去重,只保留最后两个 T NIL
也就是 (5 6) 了
(setq tester (list 0 1 2 3 4 5 6))
(delete-duplicates tester :key #'oddp) => (5 6)
RMS 嫌弃 CL 里面各种带 keyword 的函数不是没有道理的
描述非常具体,多谢你的详细回复哈!