Antworten:
Die map
Methode 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]
Array
und Range
sind unzählige Typen. map
mit 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
map
als wäre esmap!
map
, zusammen mit select
und each
ist 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 map
Vorgängen verbunden. Study map
& select
, sie sind einige der nützlichsten Ruby-Methoden in der Primärbibliothek. Sie sind genauso wichtig wie each
.
( map
ist 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 map
auf 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 Enumerable
Objekt, 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 params
handelt 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:Fixnum
in 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)
.
private
innerhalb der Klasse deklariert, in der Sie Ihre Methode abgelegt haben, bevor Sie Ihre Methode
0..param_count
bedeutet "bis einschließlich param_count".
0...param_count
bedeutet "bis zu, aber ohne param_count".
Range#map
gibt 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#map
konvertiert es aber tatsächlich in ein Array.
Enumerable
wie 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
#each
fü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
#map
Wendet 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()}
map
ist 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! :)