重点是,如果你很了解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 之外的每个值都是 true。
(lambda (x) x) 是恒等函数,与#lang racket 中的identity 相同。它返回自己的参数。
(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 的代码创建了2 个列表。因此,虽然 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))))