Antworten:
Die mapMethode verwendet ein aufzählbares Objekt und einen Block und führt den Block für jedes Element aus, wobei jeder zurückgegebene Wert aus dem Block ausgegeben wird (das ursprüngliche Objekt bleibt unverändert, es sei denn, Sie verwenden map!):
[1, 2, 3].map { |n| n * n } #=> [1, 4, 9]
Arrayund Rangesind unzählige Typen. mapmit einem Block gibt ein Array zurück. map!mutiert das ursprüngliche Array.
Wo ist das hilfreich und was ist der Unterschied zwischen map!und each? Hier ist ein Beispiel:
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
Die Ausgabe:
Danil is a programmer
Edmund is a programmer
mapals wäre esmap!
map, zusammen mit selectund eachist eines von Rubys Arbeitspferden in meinem Code.
Sie können damit eine Operation für jedes Objekt Ihres Arrays ausführen und alle an derselben Stelle zurückgeben. Ein Beispiel wäre, ein Array von Zahlen um eins zu erhöhen:
[1,2,3].map {|x| x + 1 }
#=> [2,3,4]
Wenn Sie eine einzelne Methode für die Elemente Ihres Arrays ausführen können, können Sie dies in einer Kurzform wie folgt tun:
Um dies mit dem obigen Beispiel zu tun, müssten Sie so etwas tun
class Numeric
def plusone
self + 1
end
end
[1,2,3].map(&:plusone)
#=> [2,3,4]
Um die kaufmännische Und-Verknüpfungstechnik einfacher zu verwenden, verwenden wir ein anderes Beispiel:
["vanessa", "david", "thomas"].map(&:upcase)
#=> ["VANESSA", "DAVID", "THOMAS"]
Das Transformieren von Daten in Ruby ist häufig mit einer Kaskade von mapVorgängen verbunden. Study map& select, sie sind einige der nützlichsten Ruby-Methoden in der Primärbibliothek. Sie sind genauso wichtig wie each.
( mapist auch ein Alias für collect. Verwenden Sie konzeptionell das, was für Sie am besten funktioniert.)
Weitere hilfreiche Informationen:
Wenn das Enumerable- Objekt, das Sie ausführeneach oder mapauf dem Sie arbeiten, eine Reihe von Enumerable-Elementen (Hashes, Arrays) enthält, können Sie jedes dieser Elemente in Ihren Blockpipes wie folgt deklarieren:
[["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
Im Fall eines Hash (auch ein EnumerableObjekt, ist ein Hash einfach ein Array von Tupeln mit speziellen Anweisungen für den Interpreter). Der erste "Pipe-Parameter" ist der Schlüssel, der zweite ist der Wert.
{:make => "audi", :color => "black", :year => 2008}.each do |k,v|
puts "#{k} is #{v}"
end
#make is audi
#color is black
#year is 2008
Um die eigentliche Frage zu beantworten:
Angenommen, es paramshandelt sich um einen Hash, ist dies der beste Weg, um ihn abzubilden: Verwenden Sie zwei Blockparameter anstelle von einem, um das Schlüssel-Wert-Paar für jedes interpretierte Tupel im Hash zu erfassen.
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:Fixnumin Rubin 2 und 'falsche Anzahl von Argumenten' in Rubin 1.9 / 1.8. Wie auch immer, ich habe ein Lambda verwendet: plusone = ->(x) { x + 1 }Nehmen Sie dann den Symbolbezeichner heraus : [1,2,3].map(&plusone).
privateinnerhalb der Klasse deklariert, in der Sie Ihre Methode abgelegt haben, bevor Sie Ihre Methode
0..param_countbedeutet "bis einschließlich param_count".
0...param_countbedeutet "bis zu, aber ohne param_count".
Range#mapgibt kein zurück Enumerable, sondern ordnet es tatsächlich einem Array zu. Es ist das gleiche wie Range#to_a.
Es "ordnet" jedem Element in einem Enumerable- in diesem Fall einem Bereich - eine Funktion zu . Es würde also den Block, der einmal für jede Ganzzahl von 0 bis übergeben wurde param_count(exklusiv - Sie haben Recht mit den Punkten), aufrufen und ein Array zurückgeben, das jeden Rückgabewert enthält.
Hier ist die Dokumentation für Enumerable#map. Es hat auch einen Alias collect.
Range#mapkonvertiert es aber tatsächlich in ein Array.
Enumerablewie jede eine zurückgab. Ich dachte es wäre so.
Map ist Teil des Aufzählungsmoduls. Sehr ähnlich zu "sammeln" Zum Beispiel:
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 bietet Werte, die durch ein Array iterieren und von den Blockparametern zurückgegeben werden.
#each#eachführt eine Funktion für jedes Element in einem Array aus. Die folgenden zwei Code-Auszüge sind äquivalent:
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#mapWendet eine Funktion auf jedes Element eines Arrays an und gibt das resultierende Array zurück. Folgendes ist äquivalent:
array = ["zero", "one", "two"]
newArray = array.map{|element| element.capitalize()}
array = ["zero", "one", "two"]
newArray = []
array.each{|element|
newArray << element.capitalize()
}
#map!#map!ist wie #map, ändert aber das Array an Ort und Stelle. Folgendes ist äquivalent:
array = ["zero", "one", "two"]
array.map!{|element| element.capitalize()}
array = ["zero", "one", "two"]
array = array.map{|element| element.capitalize()}
mapist eine gebräuchliche "funktionale" Methode für Enumerable-Objekte, die zum Transformieren der Werte in einer Sequenz verwendet werden (mit besonderen Überlegungen)...und...sind Möglichkeiten, Bereiche zu erstellen. Auch vertraut mit dem REPL, wo Sie das Zeug selbst ausprobieren können! :)