Массив # каждый против массива # карта


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"

Единственная разница в том, что для случая 1 используется vs.mapслучай 2 vs.each.

Что здесь случилось?

Ответы:


174

Array#each выполняет заданный блок для каждого элемента массива, а затем возвращает сам массив.

Array#map также выполняет данный блок для каждого элемента массива, но возвращает новый массив, значения которого являются возвращаемыми значениями каждой итерации блока.

Пример: предположим, что у вас есть массив, определенный таким образом:

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

Затем попробуйте выполнить each:

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

Обратите внимание, что возвращаемое значение - это просто тот же массив. Код внутри eachблока выполняется, но вычисленные значения не возвращаются; и поскольку код не имеет побочных эффектов, этот пример не выполняет никакой полезной работы.

Напротив, вызов mapметода массива возвращает новый массив, элементы которого являются возвращаемыми значениями каждого раунда выполнения mapблока:

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

Прекрасный ответ, чтобы понять. Просто .. Отказ от ответственности: если вы злоупотребляете возвращаемым значением функции карты, вы потенциально можете потратить много памяти.
Имран Ахмад

33

Эти побочные эффекты такие же , которые добавляют некоторую путаницу в вашу обратную инженерию.

Да, оба перебирают массив (фактически, все, что смешивается в Enumerable ), но map вернет массив, состоящий из результатов блока, в то время как каждый просто вернет исходный массив.

Возвращаемое значение каждого из них - это просто исходный массив, который редко используется в коде Ruby, но map - один из наиболее важных функциональных инструментов .

Что mapделает, так это возвращает массив, содержащий результаты переданного блока или именованного метода. Например:

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

В этом случае я передал не блок, а просто объект Symbol, однако у class Symbolобъектов есть to_procметод, который приведет к:

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

Кстати, вам может быть сложно найти документацию, потому что карта - это метод в Enumerable а каждый (один метод, требуемый модулем Enumerable ) - это метод в Array .

Небольшое примечание: реализация карты основана на каждом .


13

Вот небольшая демонстрация того, чем карта отличается от каждого

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

Вы видите, что карта возвращается, ["map_a", "map_b", "map_c"]тогда как каждая из них просто выполняет итерацию, но возвращает исходный массив:["a", "b", "c"] .

Таким образом, каждый из них используется для обработки массива, а карта используется для чего-то с обработанным массивом.


4

.each возвращает тот же массив, который вы предоставили изначально:

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

.map возвращает новый массив из результатов каждого вызова блока:

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

1

Массив # каждый метод возвращает один и тот же массив

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

Метод Array # map возвращает новый массив

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

когда вы используете карту для хэша, он неявно преобразует хеш в массив, поэтому у вас есть

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

vs.each {...} возвращает только последнюю оценку, которая равна [11, 22] для ["d", [11, 22]] и [33, 44, 55] для ["f", [ 33, 44, 55]]. Итак, перед последним присоединением у вас есть

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

0

Вы также можете использовать mapс Bang, map!который изменяет исходный массив


Это не ответ на вопрос. вопрос заключается в разнице между each, который выполняет данный блок и возвращает исходный массив; и map, который возвращает массив с результатом выполнения блока в виде значений
Сэмпсон Кроули
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.