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

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

params = (0...param_count).map

6 ответов


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

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

Array и Range типы перечислимые. map with a block возвращает массив. 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

map вместе с select и each - одна из рабочих лошадок Руби в моем коде.

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

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

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

  1. чтобы сделать это с приведенным выше примером, вам нужно будет сделать что-то вроде этого!--20-->

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

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

преобразование данных в Ruby часто включает каскад map операции. Учись!--6--> & select, они являются одними из самых полезных методов Ruby в основной библиотеке. Они так же важны, как each.

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

больше полезной информации:

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

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

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

{: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

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

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


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

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

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

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

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


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

  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}

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