【发布时间】:2020-11-18 00:19:39
【问题描述】:
我正在努力学习 Scheme,但我很难理解 map 和 apply 之间的区别。
据我了解,map 将函数应用于列表的每个元素,apply 将某些内容应用于过程的参数。
它们可以互换使用吗?
【问题讨论】:
标签: scheme
我正在努力学习 Scheme,但我很难理解 map 和 apply 之间的区别。
据我了解,map 将函数应用于列表的每个元素,apply 将某些内容应用于过程的参数。
它们可以互换使用吗?
【问题讨论】:
标签: scheme
他们不一样!他们的名字实际上可以帮助记住哪个做什么。
map 将把一个过程和一个或多个列表作为参数。
该过程将为列表的每个位置调用一次,使用该位置的元素列表作为参数:
(map - '(2 3 4))
; => (-2 -3 -4)
map 调用 (- 2)、(- 3)、(- 4) 来构建列表。
(map + '( 1 2 3)
'(10 20 30))
; => (11 22 33)
map 调用 (+ 1 10) (+ 2 20) (+ 3 30) 来构建列表。
(map * '(2 2 -1)
'(0 3 4)
'(5 4 2))
; => (0 24 -8)
map 调用 (* 2 0 5) (* 2 3 4) (* -1 4 2) 来构建列表。
map 有这个名字是因为它在一组值(在列表中)上实现了一个“映射”(函数):
(map - '(2 3 4))
arguments mapping "-" result
2 === (- 2) ===> -2
3 === (- 3) ===> -3
4 === (- 4) ===> -4
(map + '( 1 2 3)
'(10 20 30))
arguments mapping "+" result
1 10 === (+ 1 10) ===> 11
2 20 === (+ 2 20) ===> 22
3 30 === (+ 3 30) ===> 33
apply 将接受至少两个 参数,其中第一个是过程,最后一个是列表。它将使用以下参数调用该过程,包括列表中的参数:
(apply + '(2 3 4))
; => 9
这和(+ 2 3 4)一样
(apply display '("Hello, world!"))
; does not return a value, but prints "Hello, world!"
这与(display "Hello, world!") 相同。
apply 在您将参数作为列表时很有用,
(define arguments '(10 50 100))
(apply + arguments)
如果您尝试在不使用apply 的情况下重写最后一行,您将意识到您需要循环遍历列表并对每个元素求和...
apply 也可以与这两个以上的参数一起使用。第一个参数必须是可调用对象(过程或延续)。最后一个必须是列表。其他(在第一个和最后一个之间)是任何类型的对象。所以调用
(apply PROC a b c ... y z '(one two ... twenty))
和调用一样
(PROC a b c ... y z one two ... twenty)
这是一个具体的例子:
(apply + 1 -2 3 '(10 20))
; => 32
这和(+ 1 -2 3 10 20)一样
apply 有这个名字,因为它允许您将一个过程“应用”到多个参数。
【讨论】:
apply 中接受任意数量的参数,但第一个需要是可调用的(过程或延续),最后一个必须是列表。中间的参数是第一个参数。(apply map list '((a b c) (1 2 3))) => ((a 1) (b 2) (c 3))
不,apply 将其第一个参数调用为过程,其余所有参数作为其参数,最后一个 - 列表 - 打开,即其内容“拼接”:
(apply f a b (list c d e)) == (f a b c d e)
例如:
(apply + 1 2 (list 3 4 5))
;值:15
这只是一个调用;而map 确实在为其第二个参数的 each 成员元素调用其第一个参数。
map 和apply 的组合使用是著名的transpose 技巧:
(apply map list '((1 2 3) (10 20 30)))
;值:((1 10) (2 20) (3 30))
【讨论】:
正如最佳答案所建议的那样,map
该过程将为列表的每个位置调用一次,使用该位置的元素列表作为参数
相比之下,apply
(apply function argument-list)
一次性将argument-list 中的参数传递给function。所以function 只被调用一次。
【讨论】: