尝试这个:
(define (deep-filter f lst)
(cond
((null? lst) '())
((and (atom? lst) (f lst)) (list lst))
((atom? lst) '())
(else (append (deep-filter f (car lst))
(deep-filter f (cdr lst))))))
这称为展平列表,诀窍是在列表中使用append
而不是cons
和打包单个元素( 中的第二种情况cond
)。请注意,这将消除所有子列表,仅返回满足谓词的元素。
如果您需要在删除空列表后保留列表结构,请改为执行以下操作:
(define (deep-filter f lst)
(cond ((null? lst)
'())
((atom? (car lst))
(if (f (car lst))
(cons (car lst) (deep-filter f (cdr lst)))
(deep-filter f (cdr lst))))
(else
(filter (compose not null?)
(cons (deep-filter f (car lst))
(deep-filter f (cdr lst)))))))
现在它将按预期工作:
(deep-filter number? '(2 (a ((c)) (b)) 6))
=> '(2 6)
(deep-filter number? '(2 (a ((c)) (1)) 6))
=>'(2 ((1)) 6)
(deep-filter number? '(2 (a ((4)) (1)) 6))
=> '(2 (((4)) (1)) 6)
(deep-filter number? '(2 (a ((4)) (1)) 6 ((((((b))))))))
=> '(2 (((4)) (1)) 6)