(define (delete-list my-list element)
(if (null? my-list)
'()
(if (eqv? (car my-list) element)
(cdr my-list)
(append (list (car my-list))
(delete-list (cdr my-list) element)))))
(delete-list '('aaa 'bbb) 'aaa)
; ==> ('aaa 'bbb)
该代码为什么不输出('bbb)
?
如何解决这个问题?
答案 0 :(得分:3)
'aaa
,而不是aaa
示例:
(define (delete-list my-list element)
(if (null? my-list)
'()
(if (equal? (car my-list) element)
(cdr my-list)
(append (list (car my-list))
(delete-list (cdr my-list) element)))))
? (delete-list '('aaa 'bbb) ''aaa)
=> ((quote bbb))
答案 1 :(得分:3)
方案有3个通用的相等谓词过程。 eq?
检查指针是否相等,eqv?
检查原始类型数字和字符是否具有相同的值。 equal?
检查值是否相同。
列表'(a b)
是一个复杂的结构,因此(eq? '(a b) '(a b)) ; ==> #f
* 1则为(equal? '(a b) '(a b)) ; ==> #t
。如果要比较列表,则此过程需要使用equal?
。
引号创建一个结构。因此,代码'x
表示(quote x)
,而'(a b)
表示(quote (a b))
,无论它出现在数据内部还是代码中。评估程序将停在第一个位置,因此'('aaa 'bbb)
变为(quote ((quote aaa) (quote bbb)))
,并且由于只有第一个quote
是代码,因此结果是数据((quote aaa) (quote bbb))
,实现可能将其可视化为{{1 }}。要在最后一个列表中创建元素,您需要将评估结果为('aaa 'bbb)
((quote aaa)
),因此您需要传递'aaa
。您可能已经了解,求值''aaa
是列表数据'aaa
,您需要(quote aaa)
来测试它们:
equal?
其他内容
作为一种样式,由于您使用嵌套的(eqv? ''aaa ''aaa) ; ==> #f *1
(equal? ''aaa ''aaa) ; ==> #t
,因此可以改用一个if
使感觉平整。
将一个元素添加到列表的开头时,应使用cond
:cons
比(cons 'a '(b c))
更为简洁,后者最终会(append (list 'a) '(b c))
添加这些内容后,我会得到:
(cons (car (list 'a)) '(b c))
请注意,如我的测试所示,您的设计仅删除了第一次出现的问题。
* 1常量数据可能会被重用。因此,由于无法更改常量数据,因此某些实现在(define (delete-list my-list element)
(cond
((null? my-list) '())
((equal? (car my-list) element) (cdr my-list))
(else (cons (car my-list)
(delete-list (cdr my-list) element)))))
(delete-list '('aaa 'bbb 'ccc 'bbb) ''bbb)
; ==> ('aaa 'ccc 'bbb)
(delete-list '(aaa bbb ccc bbb) 'bbb)
; ==> (aaa ccc bbb)
上返回#t
,因此对于实现来说,重用一个值是安全的。一些实现仅在编译时执行此操作,但在解释时会重新创建常量数据。
答案 2 :(得分:1)
您不需要在引号内引用内容。因此,只需使用'(aaa bbb)
作为输入即可。