web-dev-qa-db-fra.com

Que fait la méthode "map" en Ruby?

Je suis nouveau en programmation. Quelqu'un peut-il expliquer ce que .map ferait dans:

params = (0...param_count).map
238
Sarah

La méthode map prend un objet énumérable et un bloc, puis exécute le bloc pour chaque élément en générant chaque valeur renvoyée du bloc (l'objet d'origine reste inchangé, sauf si vous utilisez map!):

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

Array et Range sont des types énumérables. map avec un bloc renvoie un tableau. map! transforme le tableau d'origine.

Où est-ce utile et quelle est la différence entre map! et each? Voici un exemple:

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

Le résultat:

Danil is a programmer
Edmund is a programmer
419
Danil Speransky

map, avec select et each est l'un des chevaux de travail de Ruby dans mon code.

Il vous permet d'exécuter une opération sur chacun des objets de votre tableau et de les renvoyer tous au même endroit. Un exemple serait d'incrémenter un tableau de nombres par un:

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

Si vous pouvez exécuter une seule méthode sur les éléments de votre tableau, vous pouvez le faire dans un style abrégé comme ceci:

  1. Pour faire cela avec l'exemple ci-dessus, vous devriez faire quelque chose comme ceci

    class Numeric
      def plusone
        self + 1
      end
    end
    [1,2,3].map(&:plusone)
    #=> [2,3,4]
    
  2. Pour utiliser plus simplement la technique du raccourci esperluette, prenons un exemple différent:

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

La transformation de données en Ruby implique souvent une cascade d'opérations map. Etudiez map & select, ce sont quelques-unes des méthodes les plus utiles Ruby de la bibliothèque primaire. Ils sont aussi importants que each.

(map est également un alias pour collect. Utilisez ce qui vous convient le mieux sur le plan conceptuel.)

Informations plus utiles:

Si l'objet Enumerable que vous exécutez each ou map on contient un ensemble d'éléments Enumerable (hachages, tableaux), vous pouvez déclarer chacun de ces éléments dans vos blocs de canaux. ainsi:

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

Dans le cas d'un hachage (également un objet Enumerable, un hachage est simplement un tableau de n-uplets avec des instructions spéciales pour l'interpréteur). Le premier "paramètre de tuyau" est la clé, le second est la valeur.

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

Pour répondre à la question:

En supposant que params soit un hachage, ce serait le meilleur moyen de mapper à travers elle: Utilisez deux paramètres de bloc au lieu d'un pour capturer la paire clé/valeur pour chaque Tuple interprété dans le hachage.

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

En utilisant Ruby 2.4, vous pouvez faire la même chose en utilisant transform_values, cette fonctionnalité extraite de Rails vers Ruby.

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

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

0..param_count signifie "jusqu'à param_count inclus". 0...param_count signifie "jusqu'à, mais sans param_count".

Range#map ne renvoie pas de Enumerable, il le mappe en réalité sur un tableau. C'est la même chose que Range#to_a.

4
Pedro Nascimento

Il "mappe" une fonction à chaque élément d'un Enumerable - dans ce cas, une plage. Donc, il appelle le bloc passé une fois pour chaque entier compris entre 0 et param_count (exclusif - vous avez raison pour les points) et renvoie un tableau contenant chaque valeur renvoyée.

Voici la documentation pour Enumerable#map. Il a également un alias, collect.

3
Ry-

La carte fait partie du module énumérable. Très similaire à "collect" Par exemple:

  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 fournit des valeurs itératives à travers un tableau qui sont renvoyées par les paramètres de bloc.

2
gkstr1