Risposte:
Il map
metodo accetta un oggetto enumerabile e un blocco ed esegue il blocco per ciascun elemento, emettendo ogni valore restituito dal blocco (l'oggetto originale rimane invariato a meno che non si usi map!)
:
[1, 2, 3].map { |n| n * n } #=> [1, 4, 9]
Array
e Range
sono tipi enumerabili. map
con un blocco restituisce un array. map!
muta l'array originale.
Dove è utile e qual è la differenza tra map!
e each
? Ecco un esempio:
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
Il risultato:
Danil is a programmer
Edmund is a programmer
map
come se fossemap!
map
, insieme a select
ed each
è uno dei cavalli di lavoro di Ruby nel mio codice.
Consente di eseguire un'operazione su ciascuno degli oggetti dell'array e di restituirli tutti nello stesso posto. Un esempio potrebbe essere l'incremento di una matrice di numeri di uno:
[1,2,3].map {|x| x + 1 }
#=> [2,3,4]
Se è possibile eseguire un singolo metodo sugli elementi dell'array, è possibile farlo in uno stile abbreviato in questo modo:
Per fare questo con l'esempio sopra, dovresti fare qualcosa del genere
class Numeric
def plusone
self + 1
end
end
[1,2,3].map(&:plusone)
#=> [2,3,4]
Per usare più semplicemente la tecnica della scorciatoia e commerciale, usiamo un esempio diverso:
["vanessa", "david", "thomas"].map(&:upcase)
#=> ["VANESSA", "DAVID", "THOMAS"]
La trasformazione dei dati in Ruby comporta spesso una serie di map
operazioni. Studia map
e select
, sono alcuni dei metodi Ruby più utili nella libreria principale. Sono importanti quanto each
.
( map
è anche un alias per collect
. Usa ciò che funziona meglio per te concettualmente.)
Altre informazioni utili:
Se l' oggetto Enumerable che stai eseguendo each
o map
su che contiene contiene un set di elementi Enumerable (hash, array), puoi dichiarare ciascuno di quegli elementi all'interno dei tubi del blocco in questo modo:
[["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
Nel caso di un hash (anche un Enumerable
oggetto, un hash è semplicemente una matrice di tuple con istruzioni speciali per l'interprete). Il primo "parametro pipe" è la chiave, il secondo è il valore.
{:make => "audi", :color => "black", :year => 2008}.each do |k,v|
puts "#{k} is #{v}"
end
#make is audi
#color is black
#year is 2008
Per rispondere alla domanda effettiva:
Supponendo che params
sia un hash, questo sarebbe il modo migliore per mapparlo: usa due parametri di blocco invece di uno per catturare la coppia chiave-valore per ogni tupla interpretata nell'hash.
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
ruby 2 e "errato numero di args" in ruby 1.9 / 1.8. In ogni caso, ho usato un lambda: plusone = ->(x) { x + 1 }
estrarre la specificatore simbolo: [1,2,3].map(&plusone)
.
private
all'interno della classe in cui hai messo il tuo metodo prima di mettere il tuo metodo
0..param_count
significa "fino a param_count compreso".
0...param_count
significa "fino a, ma non incluso param_count".
Range#map
non restituisce un Enumerable
, in realtà lo mappa su un array. È lo stesso di Range#to_a
.
"Mappa" una funzione per ciascun elemento in un Enumerable
- in questo caso, un intervallo. Quindi chiamerebbe il blocco passato una volta per ogni numero intero da 0 a param_count
(esclusivo - hai ragione circa i punti) e restituirebbe un array contenente ogni valore di ritorno.
Ecco la documentazione per Enumerable#map
. Essa ha anche un alias, collect
.
Range#map
realtà lo converte in un array.
Enumerable
, come ciascuna. Ho pensato di si.
La mappa fa parte del modulo enumerabile. Molto simile a "raccogliere" per esempio:
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}
Mappa fornisce valori che ripetono in un array restituiti dai parametri del blocco.
#each
#each
esegue una funzione per ciascun elemento in un array. I seguenti due estratti di codice sono equivalenti:
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
applica una funzione a ciascun elemento di un array, restituendo l'array risultante. Sono equivalenti:
array = ["zero", "one", "two"]
newArray = array.map{|element| element.capitalize()}
array = ["zero", "one", "two"]
newArray = []
array.each{|element|
newArray << element.capitalize()
}
#map!
#map!
è come #map
, ma modifica l'array in atto. Sono equivalenti:
array = ["zero", "one", "two"]
array.map!{|element| element.capitalize()}
array = ["zero", "one", "two"]
array = array.map{|element| element.capitalize()}
map
è un metodo "funzionale" comune trovato su oggetti Enumerable utilizzati per trasformare i valori in una sequenza (con considerazioni speciali)...
e...
sono modi di creare intervalli. Inoltre, familiarizza con la REPL, dove puoi provare queste cose da solo! :)