Je suis nouveau en programmation. Quelqu'un peut-il expliquer ce que .map
ferait dans:
params = (0...param_count).map
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
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:
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]
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
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}
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
.
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
.
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.