Scheme 使用foldr编写过滤函数?

Scheme 使用foldr编写过滤函数?,scheme,racket,fold,filterfunction,Scheme,Racket,Fold,Filterfunction,当前正在尝试编写一个过滤器函数,该函数接受一个过程列表和一个数字列表,删除在数字列表的每个元素上都不返回true的过程 我所做的是如下所示,目前只执行一个过程,并在列表中运行,以创建一个列表,说明每个元素的过程是true还是false 使用foldr或map(如果需要)(非递归) 如果程序至少有一个#f,如何删除该程序 i、 e。 目前 > (my-filter even? '(1 2 3 4)) (#f #t #f #t) > (my-filter even? (2 4)) (#t

当前正在尝试编写一个过滤器函数,该函数接受一个过程列表和一个数字列表,删除在数字列表的每个元素上都不返回true的过程

我所做的是如下所示,目前只执行一个过程,并在列表中运行,以创建一个列表,说明每个元素的过程是true还是false

使用foldr或map(如果需要)(非递归)

如果程序至少有一个#f,如何删除该程序

i、 e。 目前

> (my-filter even? '(1 2 3 4))
(#f #t #f #t)
> (my-filter even? (2 4))
(#t #t)
想要


从一些一厢情愿的想法开始。假设我们知道,对于任何给定的
f

(define (my-filter fs xs)
  (foldr (λ (f y)
           (if (every? f xs)
               (cons f y)
               y))
         '()
         fs))
现在让我们定义
every?

(define (every? f xs)
  (cond [(null? xs) #t]
        [(f (car xs)) (every? f (cdr xs))]
        [else #f]))
让我们检查一下它的
(列出偶数?

即使
foldl
会给您一个相反的输出,我仍然认为在这种情况下使用
foldl
会更好。只要我的2美分


从一些一厢情愿的想法开始。假设我们知道,对于任何给定的
f

(define (my-filter fs xs)
  (foldr (λ (f y)
           (if (every? f xs)
               (cons f y)
               y))
         '()
         fs))
现在让我们定义
every?

(define (every? f xs)
  (cond [(null? xs) #t]
        [(f (car xs)) (every? f (cdr xs))]
        [else #f]))
让我们检查一下它的
(列出偶数?

即使
foldl
会给您一个相反的输出,我仍然认为在这种情况下使用
foldl
会更好。只要我的2美分


您可以通过使用Racket的内置过程来解决这个问题,该过程测试列表中所有元素的条件是否为真,如下所示:

(define (my-filter ps xs)
  (foldr (lambda (f acc)
           (if (andmap f xs) ; if `f` is true for all elements in `xs`
               (cons f acc)  ; then add `f` to the accumulated output
               acc))         ; otherwise leave the accumulator alone
         '()                 ; initially the accumulator is an empty list
         ps))                ; iterate over the list of functions
请注意,我们不会从输出列表中“删除”函数,而是在每个步骤中决定是否将它们添加到输出列表中

它的优点是,它保留了与输入列表相同的顺序,如果这不是一个要求,则效率更高,因为它在内部使用尾部递归。无论哪种方式,它都能按预期工作:

(my-filter (list even?) '(1 2 3 4))
=> '()

(my-filter (list even?) '(2 4))
=> '(#<procedure:even?>)
(我的过滤器(列表偶数?)(1 2 3 4)
=> '()
(我的过滤器(列表偶数?)(2 4)
=> '(#)

您可以通过使用Racket的内置程序来解决这个问题,该程序测试列表中所有元素的条件是否为真-如下所示:

(define (my-filter ps xs)
  (foldr (lambda (f acc)
           (if (andmap f xs) ; if `f` is true for all elements in `xs`
               (cons f acc)  ; then add `f` to the accumulated output
               acc))         ; otherwise leave the accumulator alone
         '()                 ; initially the accumulator is an empty list
         ps))                ; iterate over the list of functions
请注意,我们不会从输出列表中“删除”函数,而是在每个步骤中决定是否将它们添加到输出列表中

它的优点是,它保留了与输入列表相同的顺序,如果这不是一个要求,则效率更高,因为它在内部使用尾部递归。无论哪种方式,它都能按预期工作:

(my-filter (list even?) '(1 2 3 4))
=> '()

(my-filter (list even?) '(2 4))
=> '(#<procedure:even?>)
(我的过滤器(列表偶数?)(1 2 3 4)
=> '()
(我的过滤器(列表偶数?)(2 4)
=> '(#)

想想:>(我的过滤器(列表偶数?)(1 2 3 4))应该返回:(列表),打字它使用
foldr
而不是
foldl
重要吗?想想:>(我的过滤器(列表偶数?)(1 2 3 4))应该返回:(列表),打字它使用
foldr
而不是
foldl
重要吗?我明白了,非常感谢!快速提问,我如何将结果返回为:(列出偶数?)而不是(#)。Cons或list似乎不起作用。
只是
偶数?
的字符串表示形式procedure@George如果只需要过程的字符串名,可以将
对象名
映射到结果列表上。看到我更新的答案了。我知道了,非常感谢!快速提问,我如何将结果返回为:(列出偶数?)而不是(#)。Cons或list似乎不起作用。
只是
偶数?
的字符串表示形式procedure@George如果只需要过程的字符串名,可以将
对象名
映射到结果列表上。请看我的最新答案。谢谢!但我怀疑我是否被允许使用andmap,因为它已经完成了几乎所有的工作D遗憾:(这是一个更好的解决方案,使用
和map
。记住这一点,当需要再次出现的时候。Óscar,感谢分享
和map
。我不知道它的存在。谢谢!但我怀疑我是否被允许使用andmap,因为它已经完成了几乎所有的工作。:D遗憾:(这是一个更好的解决方案,使用
和map
。记住它,当需要再次出现的时候。Óscar,感谢分享
和map
。我不知道它的存在。
(my-filter (list even?) '(1 2 3 4))
=> '()

(my-filter (list even?) '(2 4))
=> '(#<procedure:even?>)