Array # each vs. Array # map


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"

Satu-satunya perbedaan adalah penggunaan kasus 1 vs.map, penggunaan kasus 2 vs.each.

Apa yang terjadi disini?

Jawaban:


174

Array#each mengeksekusi blok yang diberikan untuk setiap elemen array, lalu mengembalikan array itu sendiri.

Array#map juga mengeksekusi blok yang diberikan untuk setiap elemen larik, tetapi mengembalikan larik baru yang nilainya adalah nilai kembalian dari setiap iterasi blok.

Contoh: asumsikan Anda memiliki array yang didefinisikan sebagai berikut:

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

Kemudian coba jalankan each:

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

Perhatikan nilai yang dikembalikan hanyalah array yang sama. Kode di dalam eachblok dijalankan, tetapi nilai yang dihitung tidak dikembalikan; dan karena kode tersebut tidak memiliki efek samping, contoh ini tidak berfungsi.

Sebaliknya, memanggil metode larik akan mapmengembalikan larik baru yang elemennya adalah nilai kembalian dari setiap putaran menjalankan mapblok:

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

Jawaban sempurna untuk dipahami. Hanya .. Penafian: Jika Anda terlalu sering menggunakan nilai kembali dari fungsi peta, Anda berpotensi membuang banyak memori.
— Imran Ahmad

33

The efek samping yang sama yang menambahkan beberapa kebingungan untuk reverse engineering Anda.

Ya, keduanya melakukan iterasi atas array (sebenarnya, atas apa pun yang bercampur di Enumerable ) tetapi map akan mengembalikan Array yang terdiri dari hasil blok sementara masing - masing hanya akan mengembalikan Array asli.

Nilai yang dikembalikan dari masing - masing hanyalah array asli dan jarang digunakan dalam kode Ruby tetapi map adalah salah satu alat fungsional yang paling penting .

Apa yang mapdilakukan adalah mengembalikan array yang berisi hasil dari blok atau metode bernama yang dilewatkan. Sebagai contoh:

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

Dalam hal ini saya tidak melewatkan satu blok tetapi hanya a Symbol, namun class Symbolobjek memiliki to_procmetode yang akan menghasilkan:

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

BTW, Anda mungkin kesulitan menemukan dokumentasi karena map adalah metode di Enumerable sedangkan masing-masing (satu metode yang diperlukan oleh modul Enumerable ) adalah metode di Array .

Sebagai catatan trivia: implementasi peta didasarkan pada masing-masing .


13

Berikut adalah demo singkat tentang perbedaan peta dari masing-masing

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"]

Anda melihat bahwa peta pengembalian ["map_a", "map_b", "map_c"]sedangkan masing-masing hanya iterates tapi mengembalikan array asli: ["a", "b", "c"].

Jadi masing-masing digunakan untuk memproses array dan peta digunakan untuk melakukan sesuatu dengan array yang diproses.


4

.each mengembalikan larik yang sama yang Anda berikan pada awalnya:

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

.map mengembalikan Array baru dari hasil setiap panggilan blok:

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

1

Array # setiap metode mengembalikan array yang sama

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

Metode array # map mengembalikan array baru

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

ketika Anda menggunakan map ke hash, itu secara implisit mentransmisikan hash ke sebuah array, jadi Anda memilikinya

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

vs. setiap {...} hanya memberikan Anda kembali evaluasi terakhir, yaitu [11, 22] untuk ["d", [11, 22]] dan [33, 44, 55] untuk ["f", [ 33, 44, 55]]. Jadi sebelum bergabung terakhir, Anda harus

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

0

Anda juga bisa menggunakan mapdengan bang map!itu mengubah array sumber


Ini bukanlah jawaban atas pertanyaan. pertanyaannya adalah tentang perbedaan antara each, yang mengeksekusi blok yang diberikan dan mengembalikan array asli; dan map, yang mengembalikan larik dengan hasil mengeksekusi blok sebagai nilai
— Sampson Crowley
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.