Je ne dis pas que Array
-> |value,index|
et Hash
-> |key,value|
n'est pas insensé (voir le commentaire d'Horace Loeb), mais je dis qu'il y a une façon saine d'envisager cet arrangement.
Lorsque je traite des tableaux, je me concentre sur les éléments du tableau (et non sur l'indice, car celui-ci est transitoire). La méthode est each with index, c'est-à-dire each+index, ou |each,index|, ou encore |value,index|
. Ceci est également cohérent avec le fait que l'indice est considéré comme un argument optionnel, par exemple, |valeur| est équivalent à |valeur,indice=nil| qui est cohérent avec |valeur,indice|.
Lorsque je traite des hachages, je me concentre souvent davantage sur les clés que sur les valeurs, et je traite généralement les clés et les valeurs dans cet ordre, soit key => value
ou hash[key] = value
.
Si vous voulez un typage en canard, alors utilisez soit explicitement une méthode définie comme l'a montré Brent Longborough, soit une méthode implicite comme l'a montré maxhawkins.
Ruby consiste à adapter le langage au programmeur, et non à adapter le programmeur au langage. C'est pourquoi il y a tant de façons de faire. Il y a tellement de façons de penser à quelque chose. En Ruby, vous choisissez celle qui est la plus proche et le reste du code tombe généralement de manière extrêmement soignée et concise.
Pour ce qui est de la question initiale, "Quelle est la "bonne" façon d'itérer dans un tableau en Ruby ?", eh bien, je pense que la façon de base (c'est-à-dire sans sucre syntaxique puissant ou puissance orientée objet) est de faire :
for index in 0 ... array.size
puts "array[#{index}] = #{array[index].inspect}"
end
Mais Ruby n'est qu'un puissant sucre syntaxique et une puissance orientée objet, mais quoi qu'il en soit voici l'équivalent pour les hachages, et les clés peuvent être ordonnées ou non :
for key in hash.keys.sort
puts "hash[#{key.inspect}] = #{hash[key].inspect}"
end
Ma réponse est donc : "La "bonne" façon d'itérer dans un tableau en Ruby dépend de vous (c'est-à-dire du programmeur ou de l'équipe de programmation) et du projet". Le meilleur programmeur Ruby fait le meilleur choix (de quelle puissance syntaxique et/ou de quelle approche orientée objet). Le meilleur programmeur Ruby continue à chercher d'autres moyens.
Maintenant, je veux poser une autre question : " Quelle est la " bonne " façon d'itérer dans une plage en Ruby à l'envers ? " ! (C'est grâce à cette question que je suis arrivé sur cette page).
C'est agréable à faire (pour les attaquants) :
(1..10).each{|i| puts "i=#{i}" }
mais je n'aime pas le faire (pour les arrières) :
(1..10).to_a.reverse.each{|i| puts "i=#{i}" }
En fait, ça ne me dérange pas trop de faire ça, mais quand j'enseigne le retour en arrière, je veux montrer à mes élèves une belle symétrie (c'est-à-dire avec une différence minimale, par exemple en ajoutant seulement un retour en arrière, ou un pas -1, mais sans modifier quoi que ce soit d'autre). Vous pouvez faire (pour la symétrie) :
(a=*1..10).each{|i| puts "i=#{i}" }
et
(a=*1..10).reverse.each{|i| puts "i=#{i}" }
que je n'aime pas beaucoup, mais tu ne peux pas faire
(*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
Vous pourriez finalement faire
class Range
def each_reverse(&block)
self.to_a.reverse.each(&block)
end
end
mais je veux enseigner le Ruby pur plutôt que les approches orientées objet (pour l'instant). Je voudrais itérer à l'envers :
- sans créer un tableau (considérer 0..1000000000)
- fonctionne pour n'importe quelle plage (par exemple, les chaînes de caractères, pas seulement les nombres entiers)
- sans utiliser de puissance orientée objet supplémentaire (c'est-à-dire sans modification de classe)
Je pense que c'est impossible sans définir un pred
ce qui implique de modifier la classe Range pour l'utiliser. Si vous pouvez le faire, veuillez me le faire savoir, sinon une confirmation d'impossibilité serait appréciée bien que ce soit décevant. Peut-être que Ruby 1.9 résout ce problème.
(Merci de votre temps pour lire ceci).