web-dev-qa-db-ja.com

mapとapplyの違いは何ですか?

Schemeを学習しようとしていますが、mapapplyの違いを理解するのに苦労しています。

私が理解しているように、mapはリストの各要素に関数を適用し、applyはプロシージャの引数に何かを適用します。

それらは交換可能に使用できますか?

16
Sarah

彼らは同じではありません!彼らの名前は、実際にどれが何をするかを思い出すのに役立ちます。

mapは、引数として1つのプロシージャと1つ以上のリストを取ります。プロシージャは、リストの各位置に対して1回呼び出され、その位置にある要素のリストを引数として使用します。

(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少なくとも2つの引数を取ります。最初の引数は手続きで、最後の引数はリストです。リスト内の引数を含め、次の引数でプロシージャを呼び出します。

(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は、これら2つの引数より多く使用することもできます。最初の引数は、呼び出し可能なオブジェクト(プロシージャまたは継続)でなければなりません。最後のものはリストでなければなりません。その他(最初と最後の間)は、任意のタイプのオブジェクトです。それで

(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は、プロシージャを複数の引数に「適用」できるため、その名前を持っています。

42
Jay

いいえ、applyは最初の引数をプロシージャとして呼び出し、残りはすべて引数として、最後の引数をリストとして開きます。つまり、その内容を「スライス」します。

(apply f a b (list c d e)) == (f a b c d e)

例えば。:

(適用+ 1 2(リスト3 4 5))
;値:15

これは1回の呼び出しです。実際、mapは、2番目の引数の各メンバー要素に対して最初の引数を呼び出しています。

mapapplyを組み合わせて使用​​すると、有名なtransposeトリックになります。

(マップリストを適用 '((1 2 3)(10 20 30)))
;値:((1 10)(2 20)(3 30))

3
Will Ness

一番上の答えが示唆したように、map

プロシージャは、リストの位置ごとに1回呼び出され、その位置にある要素のリストを引数として使用します

対照的に、apply

(apply function argument-list)

argument-listの引数をfunctionに一度に渡します。したがって、functionは一度だけ呼び出されます。

0
GraceMeng