我正试图了解count的作用。
我已经阅读了文档,上面写着:
返回(长度(filter-map proc lst ...),但不构建 中间列表。
然后,我已阅读filter-map文档,内容为:
返回(过滤器(lambda(x)x)(map proc lst ...)),但不包含 建立中间列表。
然后,我已经阅读了filter文档,并且我理解了。
但是,我不了解filter-map。特别是(lambda (x) x)
中的(filter (lambda (x) x) (map proc lst ...))
。
filter
和filter-map
有什么区别?
顺便说一下,filter
和filter-map
的示例也是如此,这使得理解它们更加困难。
答案 0 :(得分:4)
我想说的是,这里的主要见识是在filter
的上下文中,您应该将(lambda (x) x)
读为not-false?
。因此,可以将filter-map的文档编写为:
返回(filter not-false? (map proc lst ...))
,但不建立中间列表,其中not-false?
可以定义为(lambda (x) x)
。
答案 1 :(得分:3)
要点是,如果您对filter
和map
十分了解,那么您可以像这样解释filter-map
。如果您不知道filter
和map
的含义,将无助于您理解。当您需要学习新知识时,通常需要使用以前的经验。例如。我可以通过说3 * 4
与3 + 3 + 3 + 3
相同来解释乘法,但是如果您不知道+
是什么,则无济于事。
filter
和filter-map
有什么区别
(filter odd? '(1 2 3 4 5)) ; ==> (1 3 5)
(filter-map odd? '(1 2 3 4 5)) ; ==> (#t #t #t))
当谓词变为真时,第一个从列表中收集原始值。在这种情况下,(odd? 1)
为真,因此1
是结果中的元素。
filter-map
不会对odd?
进行过滤,就像您将odd?
传递给map
一样。在那里,您将得到一个包含结果的新列表。
(map odd? '(1 2 3 4 5)) ; ==> (#t #f #t #f #t #f)
然后它会删除错误值,这样您只剩下真实值:
(filter identity (map odd? '(1 2 3 4 5))) ; ==> (#t #t #t)
现在。重要的是要了解,在Scheme中,除#f
之外的每个值都是真实的。
(lambda (x) x)
是身份函数,与identity
中的#lang racket
相同。它返回自己的参数。
(filter identity '(1 #f 2 #f 3)) ; ==> (1 2 3)
count
的工作方式与filter-map
相同,只是它只返回您将要获得的元素数。因此:
(count odd? '(1 2 3 4 5)) ; ==> 3
现在提到它与以下内容相同:
(length (filter identity (map odd? '(1 2 3 4 5)))
使用这样的代码map
,filter
和length
创建两个列表的事实。因此,虽然count的功能相同,但无需使用map
和filter
。现在看来这是原始的,但是您可以这样:
(define (count fn lst)
(let loop ((lst lst) (cnt 0))
(cond ((null? lst) cnt)
((fn (car lst)) (loop (cdr lst) (add1 cnt)))
(else (loop (cdr lst) cnt))))