array - ¿Qué hace el método de "mapa" en Ruby?
ruby reduce (6)
"Mapea" una función a cada elemento en un Enumerable
, en este caso, un rango. Por lo tanto, llamaría al bloque que se pasa una vez por cada entero desde 0 a param_count
(exclusivo: tiene razón sobre los puntos) y devolverá una matriz que contiene cada valor de retorno.
Aquí está la documentación para Enumerable#map
. También tiene un alias, collect
.
Soy nuevo en la programación. ¿Puede alguien explicar lo que haría .map
en:
params = (0...param_count).map
El método de map
toma un objeto enumerable y un bloque, y ejecuta el bloque para cada elemento, generando cada valor devuelto desde el bloque (el objeto original no se modifica a menos que use el map!)
:
[1, 2, 3].map { |n| n * n } #=> [1, 4, 9]
Array
y Range
son tipos enumerables. map
con un bloque devuelve un Array. map!
muta la matriz original.
¿Dónde es útil, y cuál es la diferencia entre el map!
y each
? Aquí hay un ejemplo:
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
La salida:
Danil is a programmer
Edmund is a programmer
El mapa es una parte del módulo enumerable. Muy similar a "recoger" Por ejemplo:
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}
El mapa proporciona valores en iteración a través de una matriz que son devueltos por los parámetros del bloque.
Usando ruby 2.4 puede hacer lo mismo usando transform_values
, esta característica extraída de rieles a ruby.
h = {a: 1, b: 2, c: 3}
h.transform_values { |v| v * 10 }
#=> {a: 10, b: 20, c: 30}
0..param_count
significa "hasta e incluyendo param_count". 0...param_count
significa "hasta, pero sin incluir param_count".
Range#map
no devuelve un Enumerable
, en realidad lo mapea a una matriz. Es lo mismo que el Range#to_a
.
map
, junto con select
y each
uno es uno de los caballos de batalla de Ruby en mi código.
Le permite ejecutar una operación en cada uno de los objetos de su matriz y devolverlos todos en el mismo lugar. Un ejemplo sería incrementar una matriz de números en uno:
[1,2,3].map {|x| x + 1 }
#=> [2,3,4]
Si puede ejecutar un solo método en los elementos de su matriz, puede hacerlo en un estilo abreviado como:
Para hacer esto con el ejemplo anterior, tendrías que hacer algo como esto
class Numeric def plusone self + 1 end end [1,2,3].map(&:plusone) #=> [2,3,4]
Para usar más simplemente la técnica de atajo con el símbolo comercial, usemos un ejemplo diferente:
["vanessa", "david", "thomas"].map(&:upcase) #=> ["VANESSA", "DAVID", "THOMAS"]
La transformación de datos en Ruby a menudo implica una cascada de operaciones de map
. Estudie el map
y select
, son algunos de los métodos Ruby más útiles en la biblioteca principal. Son tan importantes como each
.
(El map
también es un alias para collect
. Utilice lo que mejor le funcione conceptualmente).
Más información útil:
Si el objeto Enumerable que está ejecutando each
o el map
contiene un conjunto de elementos Enumerables (hashes, arreglos), puede declarar cada uno de esos elementos dentro de sus tuberías de bloque de la siguiente manera:
[["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
En el caso de un Hash (también un objeto Enumerable
, un Hash es simplemente una matriz de tuplas con instrucciones especiales para el intérprete). El primer "parámetro de tubería" es la clave, el segundo es el valor.
{:make => "audi", :color => "black", :year => 2008}.each do |k,v|
puts "#{k} is #{v}"
end
#make is audi
#color is black
#year is 2008
Para responder a la pregunta actual:
Suponiendo que params
es un hash, esta sería la mejor manera de asignarlo: use dos parámetros de bloque en lugar de uno para capturar el par de clave y valor para cada tupla interpretada en el hash.
params = {"one" => 1, "two" => 2, "three" => 3}
params.each do |k,v|
puts "#{k}=#{v}"
end
# one=1
# two=2
# three=3