我正在努力学习Scheme,而我很难理解map
和apply
之间的区别。
据我了解,map
将函数应用于列表的每个元素,apply
将某些内容应用于过程的参数。
它们可以互换使用吗?
答案 0 :(得分:32)
他们不一样!他们的名字实际上可以帮助记住哪些做了什么。
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”(函数):
(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
具有该名称,因为它允许您将过程“应用”到多个参数。
答案 1 :(得分:3)
不,apply
将其第一个参数称为一个过程,其余的作为其参数,最后一个 - 列表 - 打开,即其内容“切入”:
(apply f a b (list c d e)) == (f a b c d e)
E.g:
(申请+ 1 2(清单3 4 5))
;价值:15
这只是一个电话; map
确实为其第二个参数的每个成员元素调用了它的第一个参数。
map
和apply
的结合使用是着名的transpose
技巧:
(应用地图清单'((1 2 3)(10 20 30)))
;价值:((1 10)(2 20)(3 30))
答案 2 :(得分:0)
建议的最高答案是map
对于列表的每个位置,将使用该位置的元素列表作为参数,对该过程调用一次。
相反,apply
(apply function argument-list)
一次将argument-list
中的参数传递给function
。因此function
仅被调用一次。