Scheme 如何从列表中删除布尔值

Scheme 如何从列表中删除布尔值,scheme,racket,Scheme,Racket,所以对于我的家庭作业,给定一个测试和一个操作,我必须计算一个列表,其中操作只在通过测试的元素上执行。例如: (选择性映射cons?长度(列表(列表12)为空(列表3))=>(列表2 1) 我在试图移除我测试失败的东西时遇到了一点麻烦。到目前为止,我得到的是 (define (testfunc test lst2) (cond [(null? lst2) null] [(false? (map (compose test) (first lst2))) (remove*

所以对于我的家庭作业,给定一个测试和一个操作,我必须计算一个列表,其中操作只在通过测试的元素上执行。例如: (选择性映射cons?长度(列表(列表12)为空(列表3))=>(列表2 1)

我在试图移除我测试失败的东西时遇到了一点麻烦。到目前为止,我得到的是

(define (testfunc test lst2)   
  (cond
    [(null? lst2) null]
    [(false? (map (compose test) (first lst2))) (remove* (list (first lst2)) (lst2))]
    [else (cons (first lst2) (testfunc test (rest lst2)))]))
当我输入以下内容来测试我的代码
(testfunc cons?(列表(列表12);(列表3))
,列表不会改变。有什么东西我看得不对吗

递归是错误的(您必须测试每个元素上的谓词,为什么是
映射
?),这不是删除元素的正确方法,
testfunc
选择性映射
不同,它们甚至没有收到相同数量的参数。让我们从头开始再试一次:

(define (selective-map test proc lst)
  (cond
    [(null? lst) null]
    [(not (test (first lst)))
     ; to remove an element we simply don't add it to the output list
     (selective-map test proc (rest lst))]
    [else
     ; on the other hand, an element that passes the test is consed to the output list
     (cons (proc (first lst)) (selective-map test proc (rest lst)))]))
更惯用的解决方案是使用折叠过程,而不是显式递归:

(define (selective-map test proc lst)
  (foldr (lambda (e acc)
           (if (test e)
               (cons (proc e) acc)
               acc))
         null
         lst))
无论哪种方式,它都能按预期工作:

(selective-map cons? length (list (list 1 2) empty (list 3)))
=> '(2 1)

我的推理是,为列表中的每个元素映射出布尔值,然后从列表中获取第一个元素,然后测试它是否为false。如果它为false,我想从列表中删除它并继续递归。如果为true,它将在新列表中记录该点并继续递归。然而,我意识到我不知道如何继续第二个cond语句的递归,因为我的另一个问题是,如果有多个空列表,它将只删除其中一个而不是全部。有什么方法可以解决这个问题吗?你需要编写一个递归处理列表的过程,你不能事先判断这个列表本身是否包含另一个列表,以及另一个列表,等等。首先,我将编写一组好的测试用例,以明确一系列样本输入的输出