Array#each
wykonuje dany blok dla każdego elementu tablicy, a następnie zwraca samą tablicę.
Array#map
wykonuje również dany blok dla każdego elementu tablicy, ale zwraca nową tablicę, której wartości są wartościami zwracanymi w każdej iteracji bloku.
Przykład: załóżmy, że masz tak zdefiniowaną tablicę:
arr = ["tokyo", "london", "rio"]
Następnie spróbuj wykonać each
:
arr.each { |element| element.capitalize }
Zwróć uwagę, że zwracana wartość to po prostu ta sama tablica. Kod wewnątrz each
bloku zostaje wykonany, ale obliczone wartości nie są zwracane; a ponieważ kod nie ma skutków ubocznych, ten przykład nie wykonuje żadnej użytecznej pracy.
W przeciwieństwie do tego wywołanie metody tablicy map
zwraca nową tablicę, której elementy są wartościami zwracanymi przez każdą rundę wykonywania map
bloku:
arr.map { |element| element.capitalize }
Te skutki uboczne są takie same, która jest dodanie trochę zamieszania do inżynierii odwrotnej.
Tak, oba iterują po tablicy (a właściwie po wszystkim, co miesza się w Enumerable ), ale map zwróci Array złożony z wyników bloku, podczas gdy każdy zwróci oryginalny Array.
Wartość zwracana każdego z nich to tylko oryginalna tablica i jest rzadko używana w kodzie Rubiego, ale mapa jest jednym z najważniejszych narzędzi funkcjonalnych .
Co
map
robi to zwraca tablicę zawierającą wyniki bloku lub metody o nazwie, która jest przekazywana. Na przykład:2.2.3 :001 > [:how, :now, :brown, :cow].map &:to_s => ["how", "now", "brown", "cow"]
W tym przypadku nie przekazałem bloku, a tylko a
Symbol
, jednakclass Symbol
obiekty mająto_proc
metodę, która spowoduje:[:how.to_s, :now.to_s, ...]
BTW, możesz mieć trudności ze znalezieniem dokumentacji, ponieważ map jest metodą w Enumerable, podczas gdy każda (jedyna metoda wymagana przez moduł Enumerable ) jest metodą w Array .
Uwaga: implementacja mapy jest oparta na każdym z nich .
źródło
Oto krótkie pokazanie, czym różni się mapa od każdej z nich
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"]
Widać, że mapa powraca
["map_a", "map_b", "map_c"]
podczas gdy każdy zaledwie iteruje ale zwraca oryginalną tablicę:["a", "b", "c"]
.Więc każdy jest używany do przetwarzania tablicy, a mapa jest używana do zrobienia czegoś z przetworzoną tablicą.
źródło
.each
zwraca tę samą tablicę, którą podałeś na początku:[1,2,3].each { |i| i + 1 } #=> [1,2,3]
.map
zwraca nowy Array z wyników każdego wywołania bloku:[1,2,3].map { |i| i + 1 } #=> [2,3,4]
źródło
Tablica # każda metoda zwraca tę samą tablicę
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
Metoda Array # map zwraca nową tablicę
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
źródło
kiedy używasz map do hasha, niejawnie rzutuje hash na tablicę, więc masz
[["d", [11, 22]], ["f", [33, 44, 55]]]
kontra każdy {...} zwraca tylko ostatnią ocenę, czyli [11, 22] dla ["d", [11, 22]] i [33, 44, 55] dla ["f", [ 33, 44, 55]]. Więc przed ostatnim dołączeniem masz
[[11, 22], [33, 44, 55]]
źródło
Możesz także użyć
map
z bang,map!
który zmienia tablicę źródłowąźródło
each
, który wykonuje dany blok i zwraca oryginalną tablicę; andmap
, która zwraca tablicę z wynikiem wykonania bloku jako wartości