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"

jedyną różnicą są przypadki użycia 1, zastosowania vs.map2 vs.each.

Co tu się stało?

Odpowiedzi:


174

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 }
# => ["tokyo", "london", "rio"]

Zwróć uwagę, że zwracana wartość to po prostu ta sama tablica. Kod wewnątrz eachbloku 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 mapzwraca nową tablicę, której elementy są wartościami zwracanymi przez każdą rundę wykonywania mapbloku:

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

Doskonała odpowiedź do zrozumienia. Tylko… Zastrzeżenie: Jeśli nadużyjesz wartości zwracanej przez funkcję mapy, możesz potencjalnie zmarnować dużo pamięci.
— Imran Ahmad

33

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, jednak class Symbolobiekty mają to_procmetodę, 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 .


13

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ą.


4

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

1

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

0

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

0

Możesz także użyć mapz bang, map!który zmienia tablicę źródłową


To nie jest odpowiedź na pytanie. pytanie dotyczy różnicy pomiędzy each, który wykonuje dany blok i zwraca oryginalną tablicę; and map, która zwraca tablicę z wynikiem wykonania bloku jako wartości
— Sampson Crowley
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.