Não estou dizendo que Array
-> |value,index|
e Hash
-> |key,value|
não é insano (veja o comentário de Horace Loeb), mas estou dizendo que existe uma maneira sensata de esperar esse arranjo.
Quando estou lidando com matrizes, estou focado nos elementos da matriz (não no índice porque o índice é transitório). O método é cada um com índice, ou seja, cada índice + ou | cada índice |, ou |value,index|
. Isso também é consistente com o índice sendo exibido como um argumento opcional, por exemplo | valor | é equivalente a | value, index = nil | que é consistente com | valor, índice |.
Quando estou lidando com hashes, geralmente estou mais focado nas chaves do que nos valores, e geralmente estou lidando com chaves e valores nessa ordem, seja key => value
ou hash[key] = value
.
Se você deseja digitar patos, use explicitamente um método definido como Brent Longborough mostrou ou um método implícito como maxhawkins mostrou.
Ruby é tudo sobre como acomodar o idioma para se adequar ao programador, não sobre o programador para se adequar ao idioma. É por isso que existem tantas maneiras. Existem muitas maneiras de pensar em algo. No Ruby, você escolhe o mais próximo e o restante do código geralmente cai de maneira extremamente clara e concisa.
Quanto à pergunta original, "Qual é a maneira" correta "de iterar através de uma matriz em Ruby?", Bem, acho que a maneira principal (ou seja, sem açúcar sintático poderoso ou poder orientado a objetos) é:
for index in 0 ... array.size
puts "array[#{index}] = #{array[index].inspect}"
end
Mas Ruby é tudo sobre açúcar sintático poderoso e poder orientado a objetos, mas de qualquer maneira aqui é o equivalente a hashes, e as chaves podem ser ordenadas ou não:
for key in hash.keys.sort
puts "hash[#{key.inspect}] = #{hash[key].inspect}"
end
Então, minha resposta é: "A maneira" correta "de iterar através de uma matriz no Ruby depende de você (ou seja, do programador ou da equipe de programação) e do projeto". O melhor programador Ruby faz a melhor escolha (de qual poder sintático e / ou qual abordagem orientada a objetos). O melhor programador de Ruby continua procurando outras maneiras.
Agora, quero fazer outra pergunta: "Qual é a maneira" correta "de percorrer um Range in Ruby de trás para frente?"! (Esta questão é como cheguei a esta página.)
É bom fazer (para a frente):
(1..10).each{|i| puts "i=#{i}" }
mas eu não gosto de fazer (para trás):
(1..10).to_a.reverse.each{|i| puts "i=#{i}" }
Bem, eu realmente não me importo muito de fazer isso, mas quando estou ensinando ao contrário, quero mostrar aos meus alunos uma simetria agradável (ou seja, com diferença mínima, por exemplo, apenas adicionando um reverso ou um passo -1, mas sem modificando qualquer outra coisa). Você pode fazer (por simetria):
(a=*1..10).each{|i| puts "i=#{i}" }
e
(a=*1..10).reverse.each{|i| puts "i=#{i}" }
que eu não gosto muito, mas você não pode fazer
(*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
Você poderia finalmente fazer
class Range
def each_reverse(&block)
self.to_a.reverse.each(&block)
end
end
mas eu quero ensinar Ruby puro em vez de abordagens orientadas a objeto (ainda). Gostaria de iterar para trás:
- sem criar uma matriz (considere 0..1000000000)
- trabalhando para qualquer intervalo (por exemplo, seqüências de caracteres, não apenas números inteiros)
- sem usar nenhum poder extra orientado a objetos (ou seja, nenhuma modificação de classe)
Eu acredito que isso é impossível sem definir um pred
método, o que significa modificar a classe Range para usá-lo. Se você puder fazer isso, entre em contato, caso contrário, a confirmação da impossibilidade seria apreciada, embora isso fosse decepcionante. Talvez o Ruby 1.9 resolva isso.
(Obrigado pelo seu tempo lendo isso.)
array#each_with_index
usa|value, key|
porque o nome do método implica a ordem, enquanto a ordem usada parahash#each
imita ahash[key] = value
sintaxe?