Mảng # mỗi so với Mảng # bản đồ


92
hash = { "d" => [11, 22], "f" => [33, 44, 55] }

# case 1
hash.map {|k,vs| vs.map {|v| "#{k}:#{v}"}}.join(",")
=> "d:11,d:22,f:33,f:44,f:55"

# case 2
hash.map {|k,vs| vs.each {|v| "#{k}:#{v}"}}.join(",")
=> "11,22,33,44,55"

chỉ khác là trường hợp 1 sử dụng vs.map, trường hợp 2 sử dụng vs.each.

Điều gì đã xảy ra ở đây?

Câu trả lời:


174

Array#each thực thi khối đã cho cho mỗi phần tử của mảng, sau đó trả về chính mảng.

Array#map cũng thực hiện khối đã cho cho mỗi phần tử của mảng, nhưng trả về một mảng mới có giá trị là giá trị trả về của mỗi lần lặp lại khối.

Ví dụ: giả sử bạn có một mảng được định nghĩa như vậy:

arr = ["tokyo", "london", "rio"]

Sau đó, hãy thử thực hiện each:

arr.each { |element| element.capitalize }
# => ["tokyo", "london", "rio"]

Lưu ý rằng giá trị trả về chỉ đơn giản là cùng một mảng. Mã bên trong eachkhối được thực thi, nhưng các giá trị được tính toán không được trả về; và vì mã không có tác dụng phụ, ví dụ này không thực hiện công việc hữu ích nào.

Ngược lại, việc gọi mapphương thức của mảng sẽ trả về một mảng mới có các phần tử là giá trị trả về của mỗi vòng thực thi mapkhối:

arr.map { |element| element.capitalize }
# => ["Tokyo", "London", "Rio"]

Câu trả lời hoàn hảo để hiểu. Chỉ là .. Tuyên bố từ chối trách nhiệm: Nếu bạn lạm dụng giá trị trả về của hàm bản đồ, bạn có thể lãng phí rất nhiều bộ nhớ.
Imran Ahmad

33

Các tác dụng phụ giống nhau, điều này gây thêm một số nhầm lẫn cho kỹ thuật đảo ngược của bạn.

Có, cả hai đều lặp lại trên mảng (trên thực tế, trên bất kỳ thứ gì kết hợp trong Enumerable ) nhưng ánh xạ sẽ trả về Mảng bao gồm các kết quả khối trong khi mỗi cái sẽ chỉ trả về Mảng ban đầu.

Giá trị trả về của mỗi chỉ là mảng ban đầu và hiếm khi được sử dụng trong mã Ruby nhưng bản đồ là một trong những công cụ chức năng quan trọng nhất .

What mapdoes là trả về một mảng chứa kết quả của khối hoặc phương thức có tên được truyền vào. Ví dụ:

    2.2.3 :001 > [:how, :now, :brown, :cow].map &:to_s
 => ["how", "now", "brown", "cow"]

Trong trường hợp này, tôi đã không chuyển một khối mà chỉ là một Symbol, tuy nhiên class Symbolcác đối tượng có một to_procphương thức dẫn đến:

[:how.to_s, :now.to_s, ...]

BTW, bạn có thể gặp khó khăn trong việc tìm tài liệu vì bản đồ là một phương thức trong Enumerable trong khi mỗi (một phương thức được yêu cầu bởi mô-đun Enumerable ) là một phương thức trong Array .

Như một lưu ý đố: việc triển khai bản đồ dựa trên từng .


13

Đây là bản trình diễn nhanh về cách bản đồ khác với từng

a = ["a", "b", "c"];
#Array.map
p a.map {|item| "map_" + item}
#prints ["map_a", "map_b", "map_c"]

#Array.each
p a.each {|item| "map_" + item}
#prints ["a", "b", "c"]

Bạn thấy rằng lợi nhuận bản đồ ["map_a", "map_b", "map_c"]trong khi mỗi chỉ lặp nhưng trả về mảng ban đầu: ["a", "b", "c"].

Vì vậy, mỗi cái được sử dụng để xử lý một mảng và bản đồ được sử dụng để làm điều gì đó với một mảng đã xử lý.


4

.each trả về cùng một mảng mà bạn đã cung cấp ban đầu:

[1,2,3].each { |i| i + 1 }
#=> [1,2,3]

.map trả về một Mảng mới từ kết quả của mỗi lệnh gọi khối:

[1,2,3].map { |i| i + 1 }
#=> [2,3,4]

1

Mảng # mỗi phương thức trả về cùng một mảng

a = [1,2,3,4,5]
a.object_id #70284994490700

b = a.each {|n| n + 2}
p b #[1,2,3,4,5]
b.object_id #70284994490700 <<--- it's the same as a

Phương thức bản đồ mảng # trả về một mảng mới

c = [1,2,3,4,5]
c.object_id #70219117705860

d = c.map {|n| n + 2}
p d #[3,4,5,6,7]
d.object_id #70284994343620  <<---- it's different than c

0

khi bạn sử dụng bản đồ thành một hàm băm, nó hoàn toàn chuyển hàm băm sang một mảng, vì vậy bạn có

[["d", [11, 22]], ["f", [33, 44, 55]]]

vs.each {...} chỉ trả lại cho bạn đánh giá cuối cùng, đó là [11, 22] cho ["d", [11, 22]] và [33, 44, 55] cho ["f", [ 33, 44, 55]]. Vì vậy, trước lần tham gia cuối cùng, bạn có

[[11, 22], [33, 44, 55]]

0

Bạn cũng có thể sử dụng mapvới bang map!đó thay đổi mảng nguồn


Đây không phải là câu trả lời cho câu hỏi. câu hỏi là về sự khác biệt giữa eachthực thi khối đã cho và trả về mảng ban đầu; và map, trả về một mảng với kết quả thực thi khối dưới dạng các giá trị
Sampson Crowley
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.