Ich will damit nicht sagen, dass Array
-> |value,index|
y Hash
-> |key,value|
ist nicht verrückt (siehe den Kommentar von Horace Loeb), aber ich sage, dass es einen vernünftigen Weg gibt, diese Vereinbarung zu erwarten.
Wenn ich mit Arrays zu tun habe, konzentriere ich mich auf die Elemente im Array (nicht auf den Index, da dieser vergänglich ist). Die Methode ist each mit index, d.h. each+index, oder |each,index|, oder |value,index|
. Dies ist auch damit vereinbar, dass der Index als optionales Argument betrachtet wird, z. B. ist |value| äquivalent zu |value,index=nil|, was mit |value,index| vereinbar ist.
Wenn ich mit Hashes zu tun habe, konzentriere ich mich oft mehr auf die Schlüssel als auf die Werte, und ich befasse mich normalerweise mit Schlüsseln und Werten in dieser Reihenfolge, entweder key => value
o hash[key] = value
.
Wenn Sie Duck-Typing wollen, dann 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 an den Programmierer anzupassen, nicht darum, dass der Programmierer sich an die Sprache anpasst. Deshalb gibt es auch so viele Möglichkeiten. Es gibt so viele Möglichkeiten, über etwas nachzudenken. In Ruby wählt man die naheliegendste, und der Rest des Codes ergibt sich in der Regel sehr sauber und präzise.
Was die ursprüngliche Frage, "Was ist der "richtige" Weg, um durch ein Array in Ruby iterieren?", nun, ich denke, der Kern Weg (dh ohne leistungsfähige syntaktische Zucker oder objektorientierte Macht) ist zu tun:
for index in 0 ... array.size
puts "array[#{index}] = #{array[index].inspect}"
end
Aber in Ruby geht es um mächtigen syntaktischen Zucker und objektorientierte Macht, aber hier ist das Äquivalent für Hashes, und die Schlüssel können geordnet sein oder nicht:
for key in hash.keys.sort
puts "hash[#{key.inspect}] = #{hash[key].inspect}"
end
Meine Antwort lautet also: "Der "richtige" Weg, um in Ruby durch ein Array zu iterieren, hängt von Ihnen (d.h. 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 weiter nach mehr Möglichkeiten.
Jetzt möchte ich eine andere Frage stellen: "Was ist der "richtige" Weg, um in Ruby rückwärts durch einen Bereich zu iterieren?"! (Diese Frage hat mich auf diese Seite geführt.)
Das ist eine schöne Sache (für die Stürmer):
(1..10).each{|i| puts "i=#{i}" }
aber ich tue es nicht gerne (für den Rückwärtsgang):
(1..10).to_a.reverse.each{|i| puts "i=#{i}" }
Ich habe eigentlich nichts dagegen, das zu tun, aber wenn ich unterrichte, rückwärts zu gehen, möchte ich meinen Schülern eine schöne Symmetrie zeigen (d.h. mit minimalen Unterschieden, z.B. nur eine Umkehrung hinzufügen, oder einen Schritt -1, aber ohne irgendetwas anderes zu ändern). Das können Sie tun (für die Symmetrie):
(a=*1..10).each{|i| puts "i=#{i}" }
y
(a=*1..10).reverse.each{|i| puts "i=#{i}" }
was ich nicht sehr mag, aber man kann nicht
(*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 schließlich Folgendes tun
class Range
def each_reverse(&block)
self.to_a.reverse.each(&block)
end
end
aber ich möchte eher reines Ruby unterrichten als objektorientierte Ansätze (noch). Ich möchte rückwärts iterieren:
- ohne ein Array zu erstellen (z.B. 0..1000000000)
- funktioniert für jeden Bereich (z. B. Strings, nicht nur Integer)
- ohne zusätzliche objektorientierte Leistung (d.h. keine Klassenänderung)
Ich glaube, das ist unmöglich, ohne eine pred
Methode, d.h. die Klasse Range muss für die Verwendung dieser Methode geändert werden. Wenn Sie dies tun können, lassen Sie mich bitte wissen, andernfalls Bestätigung der Unmöglichkeit würde geschätzt werden, obwohl es enttäuschend wäre. Vielleicht Ruby 1.9 Adressen dies.
(Danke, dass Sie sich die Zeit genommen haben, dies zu lesen.)