Co robi metoda "map" w Rubim?

Jestem nowy w programowaniu. Czy ktoś może wyjaśnić co .map zrobi w:

params = (0...param_count).map
Author: Danil Speransky, 2012-08-23

6 answers

Metoda map pobiera obiekt wyliczeniowy i blok i uruchamia blok dla każdego elementu, wyprowadzając każdą zwróconą wartość z bloku (oryginalny obiekt jest niezmieniony, chyba że użyjesz map!):

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

Array i Range są typami liczbowymi. map z blokiem zwraca tablicę. map! mutuje oryginalną tablicę.

Gdzie jest to pomocne i jaka jest różnica między map! a each? Oto przykład:

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

Wyjście:

Danil is a programmer
Edmund is a programmer
 401
Author: Danil Speransky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-05 17:42:05

map, wraz z select i each jest jednym z końców roboczych Rubiego w moim kodzie.

Pozwala na uruchomienie operacji na każdym z obiektów tablicy i zwrócenie ich wszystkich w tym samym miejscu. Przykładem może być zwiększenie tablicy liczb o jeden:

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

Jeśli możesz uruchomić jedną metodę na elementach tablicy, możesz to zrobić w stylu stenograficznym jak tak:

  1. Aby to zrobić z powyższym przykładem, musiałbyś zrobić coś takiego to

    class Numeric
      def plusone
        self + 1
      end
    end
    [1,2,3].map(&:plusone)
    #=> [2,3,4]
    
  2. Aby po prostu użyć techniki skrótu ampersand, użyjmy innego przykładu:

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

Przekształcanie danych w Rubim często wiąże się z kaskadą map operacji. Badanie map & select, są to jedne z najbardziej przydatnych metod Rubiego w podstawowej bibliotece. Są tak samo ważne jak each.

(map jest również aliasem dla collect. Użyj tego, co działa najlepiej dla Ciebie koncepcyjnie.)

Bardziej pomocne informacje:

Jeśli obiekt Enumerable, na którym uruchamiasz each lub map, zawiera zestaw elementów Enumerable (hashów, tablic), możesz zadeklarować każdy z tych elementów wewnątrz twoich rur blokowych w następujący sposób:

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

W przypadku obiektu Hash (również obiektu Enumerable, Hash jest po prostu tablicą krotek ze specjalnymi instrukcjami dla interpretera). Pierwszy "parametr rury" jest kluczem, drugi jest wartością.

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

Aby odpowiedzieć na rzeczywiste pytanie:

Zakładając, że params jest skrótem, jest to najlepszy sposób na odwzorowanie go: użyj dwóch parametrów bloku zamiast jednego, aby uchwycić parę klucz i wartość dla każdej zinterpretowanej krotki w haśle.

params = {"one" => 1, "two" => 2, "three" => 3}
params.each do |k,v|
  puts "#{k}=#{v}"
end
# one=1
# two=2
# three=3
 58
Author: boulder_ruby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-24 02:38:59

0..param_count oznacza "do param_count włącznie". 0...param_count oznacza "Do, ale nie włączając param_count".

Range#map nie zwraca Enumerable, w rzeczywistości mapuje ją do tablicy. To to samo co Range#to_a.

 4
Author: Pedro Nascimento,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-23 19:15:04

Używając ruby 2.4 możesz zrobić to samo używając transform_values, tej funkcji wyodrębnionej z rails do ruby.

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

h.transform_values { |v| v * 10 }
 #=> {a: 10, b: 20, c: 30}
 4
Author: tokhi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-08 16:52:47

To "mapuje" funkcję do każdego elementu w Enumerable - w tym przypadku zakres. Wywołałby więc blok przekazany raz dla każdej liczby całkowitej od 0 do param_count (exclusive-masz rację co do kropek) i zwrócił tablicę zawierającą każdą zwracaną wartość.

Oto dokumentacja Enumerable#map. ma również pseudonim, collect.

 3
Author: Ry-,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-23 03:56:02

Mapa jest częścią modułu wyliczeniowego. Bardzo podobne do" collect " na przykład:

  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 dostarcza wartości iteracyjne poprzez tablicę, które są zwracane przez parametry bloku.

 1
Author: gkstr1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-16 21:46:50