Я пытаюсь изучить Схему, и мне трудно понять разницу между map
и apply
.
Как я понимаю, map
применяет функцию к каждому элементу списка, а apply
применяет что-то к аргументам процедуры.
Можно ли их использовать взаимозаменяемо?
Я пытаюсь изучить Схему, и мне трудно понять разницу между map
и apply
.
Как я понимаю, map
применяет функцию к каждому элементу списка, а apply
применяет что-то к аргументам процедуры.
Можно ли их использовать взаимозаменяемо?
Они не то же самое! Их имена могут действительно помочь вспомнить, что делает.
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 f a b (list c d e)) == (f a b c d e)
например:.
(применить + 1 2 (список 3 4 5))
; Значение: 15
Это всего лишь один вызов; map
действительно вызывает свой первый аргумент для каждого элемента-члена его второго аргумента.
Одно совместное использование map
и apply
- это знаменитый трюк transpose
:
(применить список карт '((1 2 3) (10 20 30)))
, Значение: ((1 10) (2 20) (3 30))
Как указано в верхнем ответе, map
Процедура будет вызываться один раз для каждой позиции списков, используя в качестве аргументов список элементов в этой позиции
Напротив, apply
(apply function argument-list)
передать аргументы в argument-list
чтобы function
все сразу. Так что function
вызывается только один раз.