编程语言:Scheme / DrRacket
我们目前正在我的comp sci课程中查看map
,filter
和foldr
。我知道这三个都可以用来创建抽象函数,但老实说我对三者之间的区别以及何时使用每个函数有点困惑。
任何人都在关心每个人的用途以及他们的不同之处?不幸的是我的书不是很清楚。
答案 0 :(得分:39)
基本思想是这三种方法都是将一些功能应用于列表的所有元素。
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)
我认为折叠是最难理解的。更直观的名称将是“累积”。我们的想法是,当您继续“结合”列表时。在日常使用中有一些功能实际上是折叠 - 总和是一个完美的例子。
(foldr + 0 '(1 2 3))
=> 6
您可以将折叠视为采用函数并将其放在列表中的每个元素之间:(foldr + 0 '(1 2 3))
与1 + 2 + 3 + 0
相同。
折叠是特殊的,因为与其他两个不同,它通常返回一个标量值 - 这是列表的元素而不是列表本身。 (这并非总是如此,但无论如何都要以这种方式考虑它。)
请注意,我可能没有完全理解代码的每一个细节 - 我只使用过不同的旧版Scheme实现,所以我可能错过了一些Racket细节。
答案 1 :(得分:2)
我可以推荐这些手指练习(以及之前的文字):
http://htdp.org/2003-09-26/Book/curriculum-Z-H-27.html#node_idx_1464