Dizi # her biri ile Dizi # eşlemesi karşılaştırması


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

tek fark durum 1 kullanım vs.map, durum 2 kullanımdır vs.each.

Burada ne oldu?

Yanıtlar:


175

Array#each dizinin her bir elemanı için verilen bloğu çalıştırır, ardından dizinin kendisini döndürür.

Array#map ayrıca dizinin her bir öğesi için verilen bloğu çalıştırır, ancak değerleri bloğun her yinelemesinin dönüş değerleri olan yeni bir dizi döndürür.

Örnek: aşağıdaki şekilde tanımlanmış bir diziniz olduğunu varsayalım:

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

Ardından şunu çalıştırmayı deneyin each:

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

Dönüş değerinin sadece aynı dizi olduğuna dikkat edin. eachBloğun içindeki kod yürütülür, ancak hesaplanan değerler döndürülmez; ve kodun hiçbir yan etkisi olmadığından, bu örnek yararlı bir çalışma yapmaz.

Buna karşılık, dizinin mapyöntemini çağırmak, elemanları mapbloğu çalıştırmanın her turunun dönüş değerleri olan yeni bir dizi döndürür :

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

Anlamak için mükemmel bir cevap. Sadece bir .. Sorumluluk reddi: Harita işlevinin dönüş değerini aşırı kullanırsanız, çok fazla bellek harcayabilirsiniz.
Imran Ahmad

33

Yan etkiler sizin ters mühendislik için bazı karışıklığı ekleyerek hangi aynıdır.

Evet, her ikisi de dizi üzerinde yinelenir (aslında, Numaralandırılabilir'de karışan herhangi bir şeyin üzerinde ), ancak harita , blok sonuçlarından oluşan bir Dizi döndürürken, her biri orijinal Diziyi döndürür.

Dönüş değeri her sadece orijinal dizidir ve nadiren Yakut kodunda kullanılır, ancak harita biridir en önemli fonksiyonel araçlar .

Ne mapyapar, geçirilen bloğun veya adlandırılmış yöntemin sonuçlarını içeren bir dizi döndürmektir. Örneğin:

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

Bu durumda bir bloğu geçmedim, sadece a Symbol, ancak class Symbolnesnelerin bir to_procyöntemi var ve sonuçta:

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

BTW, çünkü belgeleri bulmakta zorlanıyorum olabilir harita bir yöntemdir Enumerable ise her (gerektirdiği bir yöntem Enumerable modülünde) bir yöntemdir Array .

Bir trivia notu olarak: harita uygulaması her birine dayanmaktadır .


13

İşte haritanın her birinden nasıl farklı olduğuna dair hızlı bir demo

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

O harita getiriler elde ["map_a", "map_b", "map_c"]her sadece dolaşır oysa ancak orijinal diziyi döndürür: ["a", "b", "c"].

Yani her biri bir diziyi işlemek için kullanılır ve harita işlenmiş bir dizi ile bir şeyler yapmak için kullanılır.


4

.each başlangıçta sağladığınız diziyi döndürür:

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

.map her blok çağrısının sonuçlarından yeni bir Dizi döndürür:

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

1

Dizi # her yöntem aynı diziyi döndürür

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

Dizi # eşleme yöntemi yeni bir dizi döndürür

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

Bir hash için map kullandığınızda, hash'i örtük olarak bir diziye atar, böylece

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

vs. her {...} size yalnızca son değerlendirmeyi geri verir, bu ["d", [11, 22]] için [11, 22] ve ["f" için [33, 44, 55], [ 33, 44, 55]]. Yani son katılmadan önce,

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

0

Kaynak dizisini değiştiren mapbang ile de kullanabilirsiniz.map!


Bu sorunun cevabı değil. soru, eachverilen bloğu çalıştıran ve orijinal diziyi döndüren arasındaki farkla ilgilidir ; ve mapbloğun değer olarak yürütülmesinin sonucuyla bir dizi döndürür
Sampson Crowley
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.