我最初使用成员函数来确定是否有更多的X.
我尝试了一些数据并发现:
如果第一个参数是符号,它们都可以工作!
但如果是缺陷结构,它们都会失败。
1.// `(a b) `((b b)(a b)(b c)(a b)) ==> `((b b)(b c)(a b))
(defun takeoutAllButLast (X L)
(cond ((null L) nil)
((equal X (first L))
(if (member X (rest L))
(takeoutAllButLast X (rest L))
L))
(t (cons (first L) (takeoutAllButLast X (rest L))))
)
)
2.//`(a b) `((a b)(b b)(a b)(b c)(a b)) ==> `((a b)(b b)(b c)(a b))
(defun takeoutSecondLast (X L)
(cond ((null L) nil)
((equal X (first L))
(if (member X (rest (member X (rest L))))
(cons (first L) (takeoutSecondLast X (rest L)))
(rest L)
)
)
(t (cons (first L) (takeoutSecondLast X (rest L))))
)
我想问的是如何确定是否还有一个元素是X,并且可以像成员函数一样使用?
为什么成员函数不能用于比较cons结构?
感谢您阅读我的问题!
答案 0 :(得分:2)
member
默认使用eql
作为其等式谓词。这在符号,数字和其他一些事情上都很好((eq 'a 'a)
始终为真,(let ((cons (cons 'a 'a))) (eql cons cons))
始终为真,但(eql (cons 'a 'a) (cons 'a 'a))
几乎从不为真。
您可以使用member
关键字将另一个相等检查程序传递给:test
,如果您使用#'equal
,您将(可能)得到您想要的内容。
如果您想使用自定义相等检查器member
致电foo
,只需执行以下操作:
(member thing-to-check-for the-list-to-check :test #'foo)