Что делает метод "map" в Ruby?

Я новичок в программировании. Может кто-нибудь объяснить, что .map будет делать в:

params = (0...param_count).map

Ответ 1

Метод map принимает перечислимый объект и блок и запускает блок для каждого элемента, выводя каждое возвращаемое значение из блока (исходный объект не изменяется, если вы не используете map!):

[1, 2, 3].map { |n| n * n } #=> [1, 4, 9]

Array и Range являются перечисляемыми типами. map с блоком возвращает массив. map! мутирует исходный массив.

Где это полезно, и в чем разница между map! и each? Вот пример:

names = ['danil', 'edmund']

# here we map one array to another, convert each element by some rule
names.map! {|name| name.capitalize } # now names contains ['Danil', 'Edmund']

names.each { |name| puts name + ' is a programmer' } # here we just do something with each element

Выход:

Danil is a programmer
Edmund is a programmer

Ответ 2

map, наряду с select и each является одним из рабочих лошадей Ruby в моем коде.

Он позволяет запускать операцию над каждым из ваших объектов массива и возвращать их все в одном месте. Примером может быть увеличение массива чисел на единицу:

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

Если вы можете запустить один метод в своих элементах массива, вы можете сделать это в стенографическом стиле:

  • Чтобы сделать это с помощью приведенного выше примера, вам нужно сделать что-то вроде этого

    class Numeric
      def plusone
        self + 1
      end
    end
    [1,2,3].map(&:plusone)
    #=> [2,3,4]
    
  • Чтобы более просто использовать технику ярлыка амперсанда, используйте другой пример:

    ["vanessa", "david", "thomas"].map(&:upcase)
    #=> ["VANESSA", "DAVID", "THOMAS"]
    

Преобразование данных в Ruby часто связано с каскадом операций map. Изучите map и select, они являются одними из наиболее полезных методов Ruby в основной библиотеке. Они так же важны, как each.

(map также является псевдонимом для collect). Используйте все, что лучше всего подходит для вас концептуально.)

Дополнительная информация:

Если объект Enumerable, на котором вы работаете each или map on, содержит набор элементов Enumerable (хэши, массивы), вы можете объявить каждый из этих элементов внутри ваших блоков так:

[["audi", "black", 2008], ["bmw", "red", 2014]].each do |make, color, year|
  puts "make: #{make}, color: #{color}, year: #{year}"
end
# Output:
# make: audi, color: black, year: 2008
# make: bmw, color: red, year: 2014

В случае объекта Hash (также объект Enumerable, Hash - это просто массив кортежей со специальными инструкциями для интерпретатора). Первый "параметр трубы" - это ключ, второй - значение.

{:make => "audi", :color => "black", :year => 2008}.each do |k,v|
    puts "#{k} is #{v}"
end
#make is audi
#color is black
#year is 2008

Чтобы ответить на реальный вопрос:

Предполагая, что params является хешем, это лучший способ его отображения: используйте два параметра блока вместо одного, чтобы захватить пару ключей и значений для каждого интерпретированного кортежа в хеше.

params = {"one" => 1, "two" => 2, "three" => 3}
params.each do |k,v|
  puts "#{k}=#{v}"
end
# one=1
# two=2
# three=3

Ответ 3

0..param_count означает "до и включая param_count". 0...param_count означает "до, но не включая param_count".

Range#map не возвращает Enumerable, он фактически сопоставляет его с массивом. Это то же самое, что и Range#to_a.

Ответ 4

Он "отображает" функцию для каждого элемента в Enumerable - в этом случае диапазон. Таким образом, он будет вызывать блок, переданный один раз для каждого целого числа от 0 до param_count (исключая - вы правы относительно точек) и возвращаете массив, содержащий каждое возвращаемое значение.

Здесь документация для Enumerable#map. У него также есть псевдоним collect.

Ответ 5

Я попробую другой способ объяснения выше:

Что делает карта

Раньше я работал в папке с копией фотографий в тот же день. Нам дали стопку бумаг. И в основном нам приходилось:

  • Ксерокопирование каждой страницы и
  • взяв новую страницу, нам нужно было отпечатать слова "CLEARED" на каждом из них.

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

Я мог бы просто легко: (i) отредактировать первую строку или (ii) полностью уничтожить новую ксерокопию.

Это в основном то, что делает функция карты: она позволяет вам преобразовывать ряд элементов во что угодно!

basket = [apple, orange, banana]

new_basket_full_of_eaten_food = basket.map { |food_item| food_item.take_a_huge_bite }

В приведенном выше случае мы превратили корзину продуктов в новую корзину с огромным укусом в каждом из фруктов. То, как оно преобразилось!

Внимание!

Как примечания @Anthony ниже, исходная корзина фруктов остается неприкасаемой: она все еще там, и там нет укусов.

Вы можете подтвердить это в рубиновой документации здесь: https://ruby-doc.org/core-2.2.0/Array.html#method-i-map

Надеюсь, это поможет вам.

Ответ 6

Используя ruby ​​2.4, вы можете сделать то же самое с помощью transform_values, эта функция извлекается из рельсов в ruby.

h = {a: 1, b: 2, c: 3}

h.transform_values { |v| v * 10 }
 #=> {a: 10, b: 20, c: 30}

Ответ 7

Карта является частью перечислимого модуля. Очень похоже на "собирать" Пример:

  Class Car

    attr_accessor :name, :model, :year

    Def initialize (make, model, year)
      @make, @model, @year = make, model, year
    end

  end

  list = []
  list << Car.new("Honda", "Accord", 2016)
  list << Car.new("Toyota", "Camry", 2015)
  list << Car.new("Nissan", "Altima", 2014)

  p list.map {|p| p.model}

Карта предоставляет значения, повторяющиеся через массив, возвращаемый параметрами блока.