No digo que Array
-> |value,index|
y Hash
-> |key,value|
no sea una locura (ver el comentario de Horace Loeb), pero sí digo que hay una forma sensata de esperar este acuerdo.
Cuando trato con matrices, me centro en los elementos de la matriz (no en el índice porque el índice es transitorio). El método es cada uno con índice, es decir, cada + índice, o | cada, índice | o |value,index|
. Esto también es coherente con el índice visto como un argumento opcional, por ejemplo | valor | es equivalente a | value, index = nil | que es consistente con | value, index |.
Cuando estoy tratando con hashes, a menudo estoy más enfocado en las claves que en los valores, y generalmente estoy tratando con claves y valores en ese orden, ya sea key => value
o hash[key] = value
.
Si desea escribir pato, entonces explícitamente use un método definido como mostró Brent Longborough, o un método implícito como mostró maxhawkins.
Ruby tiene que ver con acomodar el lenguaje para adaptarse al programador, no para que el programador se adapte al lenguaje. Por eso hay tantas formas. Hay muchas maneras de pensar en algo. En Ruby, eliges el más cercano y el resto del código generalmente se cae de manera extremadamente clara y concisa.
En cuanto a la pregunta original, "¿Cuál es la forma" correcta "de iterar a través de una matriz en Ruby?" Bueno, creo que la forma central (es decir, sin poder sintáctico potente o poder orientado a objetos) es hacer:
for index in 0 ... array.size
puts "array[#{index}] = #{array[index].inspect}"
end
Pero Ruby tiene que ver con el poderoso azúcar sintáctico y el poder orientado a objetos, pero de todos modos aquí es el equivalente para los hashes, y las claves se pueden ordenar o no:
for key in hash.keys.sort
puts "hash[#{key.inspect}] = #{hash[key].inspect}"
end
Entonces, mi respuesta es: "La forma" correcta "de recorrer una matriz en Ruby depende de usted (es decir, del programador o del equipo de programación) y del proyecto". El mejor programador de Ruby hace la mejor elección (de qué poder sintáctico y / o qué enfoque orientado a objetos). El mejor programador de Ruby continúa buscando más formas.
Ahora, quiero hacer otra pregunta, "¿Cuál es la forma" correcta "de recorrer un rango en Ruby hacia atrás?" (Esta pregunta es cómo llegué a esta página).
Es bueno hacer (para los delanteros):
(1..10).each{|i| puts "i=#{i}" }
pero no me gusta hacer (al revés):
(1..10).to_a.reverse.each{|i| puts "i=#{i}" }
Bueno, en realidad no me importa hacer eso demasiado, pero cuando enseño hacia atrás, quiero mostrarles a mis estudiantes una buena simetría (es decir, con una diferencia mínima, por ejemplo, solo agregando un reverso o un paso -1, pero sin modificando cualquier otra cosa). Puedes hacer (por simetría):
(a=*1..10).each{|i| puts "i=#{i}" }
y
(a=*1..10).reverse.each{|i| puts "i=#{i}" }
que no me gusta mucho, pero no puedes hacer
(*1..10).each{|i| puts "i=#{i}" }
(*1..10).reverse.each{|i| puts "i=#{i}" }
#
(1..10).step(1){|i| puts "i=#{i}" }
(1..10).step(-1){|i| puts "i=#{i}" }
#
(1..10).each{|i| puts "i=#{i}" }
(10..1).each{|i| puts "i=#{i}" } # I don't want this though. It's dangerous
En última instancia, podrías hacer
class Range
def each_reverse(&block)
self.to_a.reverse.each(&block)
end
end
pero quiero enseñar Ruby puro en lugar de enfoques orientados a objetos (todavía). Me gustaría repetir al revés:
- sin crear una matriz (considere 0..1000000000)
- trabajando para cualquier rango (por ejemplo, cadenas, no solo enteros)
- sin usar ningún poder adicional orientado a objetos (es decir, sin modificación de clase)
Creo que esto es imposible sin definir un pred
método, lo que significa modificar la clase Range para usarlo. Si puede hacer esto, hágamelo saber, de lo contrario se agradecería la confirmación de imposibilidad, aunque sería decepcionante. Quizás Ruby 1.9 aborde esto.
(Gracias por tu tiempo leyendo esto).
array#each_with_index
usa|value, key|
porque el nombre del método implica el orden, mientras que el orden utilizado parahash#each
imita lahash[key] = value
sintaxis.