编程语言:Scheme/DrRacket
我们目前正在复习map
、、filter
和foldr
在我的计算机科学课上。我知道这三个都可以用来创建抽象函数,但老实说,我对这三个之间的区别以及何时使用它们感到有些困惑。
有谁愿意解释每个的用途以及它们有何不同?不幸的是,我的书不是很清楚。
编程语言:Scheme/DrRacket
我们目前正在复习map
、、filter
和foldr
在我的计算机科学课上。我知道这三个都可以用来创建抽象函数,但老实说,我对这三个之间的区别以及何时使用它们感到有些困惑。
有谁愿意解释每个的用途以及它们有何不同?不幸的是,我的书不是很清楚。
基本思想是这三种方法都是将某些功能应用于列表的所有元素的方法。
Map 可能是最简单的——您只需将函数应用于列表的每个元素。这与其他语言中的 for-each 循环基本相同:
(map (lambda (x) (+ x 1)) '(1 2 3))
=> (2 3 4)
基本上,地图是这样(map f '(1 2 3))
的:与(list (f 1) (f 2) (f 3))
.
过滤器也很简单:该函数就像一个仲裁器,决定是否保留每个数字。想象一个非常挑食的人浏览菜单并抱怨他不会吃的东西;)
(filter (lambda (x) (equal? x 1)) '(1 2 3))
=> (1)
我认为折叠是最难理解的。更直观的名称是“累积”。这个想法是您在进行过程中“组合”列表。日常使用中有一些函数实际上是折叠的——sum 就是一个很好的例子。
(foldr + 0 '(1 2 3))
=> 6
您可以将折叠视为获取函数并将其放在列表中的每个元素之间:(foldr + 0 '(1 2 3))
与1 + 2 + 3 + 0
.
Fold 之所以特殊,是因为与其他两个不同,它通常返回一个标量值——该值是列表的元素,而不是列表本身。(这并不总是正确的,但无论如何现在都这样想。)
请注意,我可能没有把代码的每一个细节都做到完美——我只使用过一个不同的、较旧的 Scheme 实现,所以我可能错过了一些 Racket 细节。
我可以推荐这些手指练习(以及前面的文字):
http://htdp.org/2003-09-26/Book/curriculum-ZH-27.html#node_idx_1464