2012-03-06 47 views
22

thể trùng lặp:
Ruby - What is the difference between map, each and collect?Sự khác biệt giữa bản đồ và mỗi

tôi luôn nhìn vào Ruby-Doc cũng nhưng tôi không thể hiểu sự khác biệt giữa

map 
each 

lặp. Nó sẽ là tuyệt vời nếu bạn có thể đưa ra một ví dụ và giải thích.

+0

... và ngoài câu trả lời của Andrew và Bryan tôi thêm rằng có một phương pháp khác gọi là * thu thập * giống hệt * bản đồ *;) –

+0

Yup, 'map' &' collect' là tương đương. Mặc dù tôi không bao giờ thích cái tên "thu thập" vì tôi không nghĩ nó thực sự mô tả những gì nó làm rất tốt. –

Trả lời

64

each chỉ cần lặp qua số đếm được cho trước, chạy khối cho từng giá trị. Nó loại bỏ các giá trị trả về của khối, và mỗi chỉ đơn giản trả về đối tượng ban đầu nó được gọi vào lúc:

[1, 2, 3].each do |i| 
    i + 1 
end # => [1, 2, 3] 

này chỉ đơn giản là một cách phổ quát hơn đẹp hơn làm một iterating for loop truyền thống, và eachnhiều ưa thích hơn for vòng trong Ruby (trên thực tế, tôi không nghĩ rằng tôi đã từng sử dụng một vòng lặp for trong Ruby).

map, tuy nhiên, lặp trên mỗi phần tử, bằng cách sử dụng giá trị trả về của khối để cư một mảng mới ở mỗi chỉ số tương ứng và gửi lại rằng mảng mới:

[1, 2, 3].map do |i| 
    i + 1 
end # => [2, 3, 4] 

Vì vậy, nó là "bản đồ" từng yếu tố để một cái mới sử dụng khối đã cho, do đó tên "bản đồ". Lưu ý rằng không phải each cũng không tự map sửa đổi bộ sưu tập gốc.

+2

Sẽ rất đáng để nhấn mạnh rằng nó không đặt bất kỳ giá trị nào trong bộ sưu tập * gốc *; chỉ trong bản sao trả về của nó. – SasQ

+0

_ "đặt phần tử hiện tại được lặp lại thành giá trị trả về" _ âm thanh như thể phần tử hiện tại đang được thay thế bằng giá trị của khối.Và _ "với những thay đổi đó" _ nhấn mạnh rằng một cái gì đó đang được thay đổi. Đó sẽ là một lời giải thích tốt cho 'Array # map! '(Với bang). Mặt khác, 'map' (cả hai' Bản đồ #' và 'Array # map') trả về một mảng mới (nó luôn luôn là mảng, bất kể người nhận) chứa các giá trị trả về bởi khối mà không thay đổi người nhận. – Stefan

+1

@Stefan Tôi có thể thấy sự nhầm lẫn, hy vọng bản cập nhật làm rõ mọi thứ một chút (điều này đã được viết một * dài * thời gian trước đây!). –

7

each trả về đối tượng gốc. Nó được sử dụng để chạy một hoạt động bằng cách sử dụng từng phần tử của một mảng mà không thu thập bất kỳ kết quả nào. Ví dụ, nếu bạn muốn in một danh sách các số, bạn có thể làm điều gì đó như thế này:

arr = [1, 2, 3, 4] 
arr.each { |n| puts n } 

Bây giờ, đó là phương pháp puts trên thực tế trả nil. Một số người không biết điều đó, nhưng dù sao cũng không quan trọng; không có lý do thực sự để thu thập giá trị đó (nếu bạn muốn chuyển đổi arr để chuỗi, bạn nên sử dụng arr.map(&:to_s) hay arr.map { |n| n.to_s }.


map trả về kết quả của khối bạn vượt qua nó. Đó là một cách tuyệt vời để chạy một hoạt động trên mỗi phần tử trong một mảng và truy xuất kết quả. Nếu bạn muốn nhiều thành phần của một mảng bằng 2, thì đây là lựa chọn tự nhiên. :

arr = [1, 2, 3, 4] 
arr.map! { |n| n * 2} 
# => [2, 4, 6, 8] 
Các vấn đề liên quan