Ich sage nicht, dass Array
-> |value,index|
und Hash
-> |key,value|
nicht verrückt sind (siehe Horace Loebs Kommentar), aber ich sage, dass es einen vernünftigen Weg gibt, dieses Arrangement zu erwarten.
Wenn ich mich mit Arrays beschäftige, konzentriere ich mich auf die Elemente im Array (nicht auf den Index, da der Index vorübergehend ist). Die Methode ist jeweils mit Index, dh jedem + Index oder | jedem Index | oder |value,index|
. Dies stimmt auch mit dem Index überein, der als optionales Argument angesehen wird, z. B. | value | entspricht | value, index = nil | Dies stimmt mit | value, index | überein.
Wenn ich mich mit Hashes beschäftige, konzentriere ich mich oft mehr auf die Schlüssel als auf die Werte, und ich beschäftige mich normalerweise entweder mit Schlüsseln und Werten in dieser Reihenfolge, entweder key => value
oder hash[key] = value
.
Wenn Sie Enten tippen möchten, verwenden Sie entweder explizit eine definierte Methode, wie Brent Longborough gezeigt hat, oder eine implizite Methode, wie Maxhawkins gezeigt hat.
Bei Ruby geht es darum, die Sprache dem Programmierer anzupassen, nicht darum, dass der Programmierer der Sprache entspricht. Deshalb gibt es so viele Möglichkeiten. Es gibt so viele Möglichkeiten, über etwas nachzudenken. In Ruby wählen Sie den nächstgelegenen und der Rest des Codes fällt normalerweise äußerst ordentlich und präzise aus.
Was die ursprüngliche Frage betrifft: "Was ist der" richtige "Weg, um ein Array in Ruby zu durchlaufen?", Nun, ich denke, der Kernweg (dh ohne starken syntaktischen Zucker oder objektorientierte Kraft) besteht darin, Folgendes zu tun:
for index in 0 ... array.size
puts "array[#{index}] = #{array[index].inspect}"
end
Aber Ruby dreht sich alles um mächtigen syntaktischen Zucker und objektorientierte Kraft, aber hier ist das Äquivalent für Hashes, und die Schlüssel können bestellt werden oder nicht:
for key in hash.keys.sort
puts "hash[#{key.inspect}] = #{hash[key].inspect}"
end
Meine Antwort lautet also: "Der" richtige "Weg, ein Array in Ruby zu durchlaufen, hängt von Ihnen (dh dem Programmierer oder dem Programmierteam) und dem Projekt ab." Der bessere Ruby-Programmierer trifft die bessere Wahl (welche syntaktische Kraft und / oder welcher objektorientierte Ansatz). Der bessere Ruby-Programmierer sucht weiterhin nach mehr Möglichkeiten.
Jetzt möchte ich eine weitere Frage stellen: "Was ist der" richtige "Weg, um einen Bereich in Ruby rückwärts zu durchlaufen?"! (Diese Frage ist, wie ich zu dieser Seite gekommen bin.)
Es ist schön zu tun (für die Stürmer):
(1..10).each{|i| puts "i=#{i}" }
aber ich mache nicht gerne (für die rückwärts):
(1..10).to_a.reverse.each{|i| puts "i=#{i}" }
Nun, es macht mir eigentlich nichts aus, das zu viel zu tun, aber wenn ich rückwärts unterrichte, möchte ich meinen Schülern eine schöne Symmetrie zeigen (dh mit minimalem Unterschied, z. B. nur eine Umkehrung oder einen Schritt -1 hinzufügen, aber ohne etwas anderes ändern). Sie können Folgendes tun (aus Symmetriegründen):
(a=*1..10).each{|i| puts "i=#{i}" }
und
(a=*1..10).reverse.each{|i| puts "i=#{i}" }
was ich nicht sehr mag, aber du kannst es nicht tun
(*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
Sie könnten letztendlich tun
class Range
def each_reverse(&block)
self.to_a.reverse.each(&block)
end
end
Aber ich möchte (noch) eher reinen Ruby als objektorientierte Ansätze lehren. Ich möchte rückwärts iterieren:
- ohne ein Array zu erstellen (0..1000000000 berücksichtigen)
- Arbeiten für jeden Bereich (z. B. Zeichenfolgen, nicht nur Ganzzahlen)
- ohne zusätzliche objektorientierte Kraft (dh keine Klassenänderung)
Ich glaube, dass dies unmöglich ist, ohne eine pred
Methode zu definieren , was bedeutet, dass die Range-Klasse geändert wird, um sie zu verwenden. Wenn Sie dies tun können, lassen Sie es mich bitte wissen, andernfalls wäre eine Bestätigung der Unmöglichkeit willkommen, obwohl dies enttäuschend wäre. Vielleicht spricht Ruby 1.9 dies an.
(Vielen Dank für Ihre Zeit beim Lesen.)
array#each_with_index
verwendet,|value, key|
weil der Methodenname die Reihenfolge impliziert, während die Reihenfolge fürhash#each
diehash[key] = value
Syntax imitiert ?