2014-12-15 92 views
9

Tôi đang cố gắng tìm hiểu Đề án và tôi gặp khó khăn trong việc tìm hiểu sự khác biệt giữa mapapply.Sự khác biệt giữa bản đồ và áp dụng trong sơ đồ là gì?

Khi tôi hiểu, map áp dụng chức năng cho từng phần tử trong danh sách và apply áp dụng điều gì đó cho các đối số của quy trình.

Chúng có thể được sử dụng thay thế cho nhau không?

Trả lời

21

Chúng không giống nhau! Tên của họ thực sự có thể giúp bạn nhớ cái nào.

map sẽ lấy làm đối số một quy trình và một hoặc nhiều danh sách. Thủ tục sẽ được gọi một lần cho mỗi vị trí của danh sách, sử dụng như các đối số danh sách các yếu tố tại vị trí đó:

(map - '(2 3 4)) 
; => (-2 -3 -4) 

map gọi (- 2), (- 3), (- 4) để xây dựng danh sách.

(map + '(1 2 3) 
     '(10 20 30)) 
; => (11 22 33) 

map gọi (+ 1 10)(+ 2 20)(+ 3 30) để xây dựng danh sách.

(map * '(2 2 -1) 
     '(0 3 4) 
     '(5 4 2)) 
; => (0 24 -8) 

map gọi (* 2 0 5)(* 2 3 4)(* -1 4 2) để xây dựng danh sách.

map có tên đó vì nó thực hiện một "bản đồ" (chức năng) trên một tập hợp các giá trị (trong danh sách):

(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 sẽ mất ít nhất hai lập luận, là người đầu tiên trong số họ là một thủ tục và danh sách cuối cùng.Nó sẽ gọi thủ tục với các đối số sau đây, kể cả những người trong danh sách:

(apply + '(2 3 4)) 
; => 9 

Đây là giống như (+ 2 3 4)

(apply display '("Hello, world!")) 
; does not return a value, but prints "Hello, world!" 

Đây là giống như (display "Hello, world!").

apply rất hữu ích khi bạn có lý lẽ như một danh sách,

(define arguments '(10 50 100)) 
(apply + arguments) 

Nếu bạn cố gắng viết lại dòng cuối cùng mà không sử dụng apply, bạn sẽ nhận ra rằng bạn cần để lặp qua danh sách tổng hợp mỗi phần tử. ..

apply cũng có thể được sử dụng với nhiều hơn hai đối số đó. Đối số đầu tiên phải là một đối tượng có thể gọi (một thủ tục hoặc một sự tiếp tục). Người cuối cùng phải là một danh sách. Những người khác (giữa người đầu tiên và người cuối cùng) là các đối tượng thuộc bất kỳ loại nào. Vì vậy, gọi

(apply PROC a b c ... y z '(one two ... twenty)) 

được giống như gọi

(PROC a b c ... y z one two ... twenty) 

Dưới đây là một ví dụ cụ thể:

(apply + 1 -2 3 '(10 20)) 
; => 32 

Đây là giống như (+ 1 -2 3 10 20)

apply đã biết tên vì nó cho phép bạn "áp dụng" một thủ tục cho một số đối số.

+1

Trong Đề án 'áp dụng' nhận bất kỳ số lượng đối số nào, nhưng yêu cầu đầu tiên phải là một cái gì đó có thể gọi (thủ tục hoặc tiếp tục) và cuối cùng phải là một danh sách. Các đối số ở giữa là các đối số đầu tiên .. '(áp dụng danh sách bản đồ '((abc) (1 2 3))) => ((a 1) (b 2) (c 3))' – Sylwester

+0

@Sylwester: vâng, Tôi đã chỉnh sửa bài đăng. Cảm ơn! – Jay

+1

Sự khác biệt quan trọng khác là bản đồ luôn trả về một danh sách. –

3

Không, apply gọi số đầu tiên của nó như là một thủ tục, với tất cả các phần còn lại như các đối số của nó, với tác phẩm mới nhất - Danh mục - mở ra, tức là nội dung của nó "thái lát trong":

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

Ví dụ:

(áp dụng + 1 2 (danh sách 3 4 5))
; Giá trị: 15

Nó chỉ là một cuộc gọi; map thực sự gọi đối số đầu tiên của nó cho mỗi thành phần của đối số thứ hai của nó.

Một sử dụng kết hợp của mapapply là nổi tiếng transpose lừa:

(áp dụng danh sách bản đồ '((1 2 3) (10 20 30)))
; Giá trị: ((1 10) (2 20) (3 30))

Các vấn đề liên quan