Je suis nouveau en programmation. Quelqu'un peut-il expliquer ce .map
qui ferait:
params = (0...param_count).map
Je suis nouveau en programmation. Quelqu'un peut-il expliquer ce .map
qui ferait:
params = (0...param_count).map
Réponses:
La map
méthode prend un objet énumérable et un bloc, et exécute le bloc pour chaque élément, produisant chaque valeur retournée à partir du bloc (l'objet d'origine est 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!
mute 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
comme si elle étaitmap!
map
, avec select
et each
est l'un des chevaux de bataille 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 de 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 ce faire avec l'exemple ci-dessus, vous devez faire quelque chose comme ça
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, utilisons un autre exemple:
["vanessa", "david", "thomas"].map(&:upcase)
#=> ["VANESSA", "DAVID", "THOMAS"]
La transformation de données dans Ruby implique souvent une cascade d' map
opérations. Etudiez map
& select
, ce sont quelques-unes des méthodes Ruby les plus utiles de la bibliothèque principale. Ils sont tout aussi importants que each
.
( map
est également un alias pour collect
. Utilisez ce qui vous convient le mieux conceptuellement.)
Plus d'informations utiles:
Si l' objet Enumerable que vous exécutez each
ou map
sur contient un ensemble d'éléments Enumerable (hachages, tableaux), vous pouvez déclarer chacun de ces éléments à l'intérieur de vos canaux de blocs comme suit:
[["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 Hash (également un Enumerable
objet, un Hash est simplement un tableau de tuples 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 vraie question:
En supposant qu'il params
s'agit d'un hachage, ce serait la meilleure façon de le mapper: 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
NoMethodError: private method 'plusone' called for 1:Fixnum
en rubis 2 et «mauvais nombre d'arguments» en rubis 1.9 / 1.8. Quoi qu'il en soit, j'ai utilisé un lambda: plusone = ->(x) { x + 1 }
prenez le spécificateur symbole: [1,2,3].map(&plusone)
.
private
intérieur de la classe où vous avez mis votre méthode avant de mettre votre méthode
0..param_count
signifie "jusqu'à et y compris param_count".
0...param_count
signifie "jusqu'à, mais sans inclure param_count".
Range#map
ne renvoie pas un Enumerable
, il le mappe en fait sur un tableau. C'est la même chose que Range#to_a
.
Il "mappe" une fonction à chaque élément d'une Enumerable
- dans ce cas, une plage. Ainsi, il appellerait le bloc passé une fois pour chaque entier de 0 à param_count
(exclusif - vous avez raison sur les points) et retournerait un tableau contenant chaque valeur de retour.
Voici la documentation de Enumerable#map
. Il a également un alias, collect
.
Range#map
convertit en fait en tableau.
Enumerable
, comme chacun. Je pensais que oui.
La carte fait partie du module énumérable. Très similaire à "collecter" 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}
La carte fournit des valeurs itératives à travers un tableau qui sont retournées par les paramètres de bloc.
#each
#each
exécute une fonction pour chaque élément d'un tableau. Les deux extraits de code suivants sont équivalents:
x = 10
["zero", "one", "two"].each{|element|
x++
puts element
}
x = 10
array = ["zero", "one", "two"]
for i in 0..2
x++
puts array[i]
end
#map
#map
applique une fonction à chaque élément d'un tableau, renvoyant le tableau résultant. Les éléments suivants sont équivalents:
array = ["zero", "one", "two"]
newArray = array.map{|element| element.capitalize()}
array = ["zero", "one", "two"]
newArray = []
array.each{|element|
newArray << element.capitalize()
}
#map!
#map!
est comme #map
, mais modifie le tableau en place. Les éléments suivants sont équivalents:
array = ["zero", "one", "two"]
array.map!{|element| element.capitalize()}
array = ["zero", "one", "two"]
array = array.map{|element| element.capitalize()}
map
est une méthode "fonctionnelle" courante trouvée sur les objets Enumerable utilisés pour transformer les valeurs dans une séquence (avec des considérations spéciales)...
et...
sont des moyens de créer des plages. De plus, familiarisez-vous avec le REPL, où vous pouvez essayer ce genre de choses vous-même! :)