Die Programmiersprache Ruby (German Edition)
jedes Element anwendet:
data = [1,2,3,4] # Eine enumerierbare Collection
roots = data.collect {|x| Math.sqrt(x)} # Sammle Wurzeln der Daten
words = %w[hello world] # Eine andere Collection
upper = words.map {|x| x.upcase } # Abbilden auf Großbuchstaben
Die Methode
zip
verschachtelt die Elemente einer enumerierbaren Collection mit den Elementen von null oder mehr anderen Collections und liefert ein Array mit Elementen (eines aus jeder Collection) an den zugehörigen Block zurück. Wenn kein Block angegeben wurde, ist der Rückgabewert in Ruby 1.8 ein Array mit Arrays oder in Ruby 1.9 ein Enumeratorobjekt (ein Aufruf von
to_a
für das Enumeratorobjekt erzeugt das Array von Arrays, das in 1.8 zurückgegeben wird):
(1..3).zip([4,5,6]) {|x| print x.inspect } # Ausgabe "[1,4][2,5][3,6]"
(1..3).zip([4,5,6],[7,8]) {|x| print x} # Ausgabe "14725836"
(1..3).zip('a'..'c') {|x,y| print x,y } # Ausgabe "1a2b3c"
Enumerable
definiert eine Methode
to_a
(und ein Synonym
entries
), das jede enumerierbare Collection in ein Array umwandelt.
to_a
ist in diesem Abschnitt aufgeführt, weil die Konvertierung offensichtlich das Iterieren über die Collection beinhaltet. Die Elemente des Ergebnis-Array stehen in der Reihenfolge, in der der Iterator
each
sie ausgibt:
(1..3).to_a # => [1,2,3]
(1..3).entries # => [1,2,3]
Wenn Sie
require 'set'
nutzen, erhalten alle
Enumerable
-Objekte zusätzlich eine Methode
to_set
. Sets werden genauer in „9.5.4 Sets“ beschrieben:
require 'set'
(1..3).to_set # => #
9.5.1.2 Enumeratoren und externe Iteratoren
Enumeratoren und ihre Verwendung als externe Iteratoren sind vollständig in „5.3.4 Enumeratoren“ und „5.3.5 Externe Iteratoren“ beschrieben. Dieser Abschnitt ist nur eine kurze Wiederholung der ausführlichen Beschreibung aus Kapitel 5 mit Beispielen.
Enumeratoren haben die Klasse
Enumerable::Enumerator
, die für ein so mächtiges Iterationskonstrukt eine überraschend kleine Zahl an Methoden besitzt. Enumeratoren sind vor allem ein Feature von Ruby 1.9, auch wenn ein Teil der Enumeratorfunktionalität schon in Ruby 1.8 vorhanden ist (dort benötigt man die Bibliothek
enumerator
). Erzeugen Sie einen
Enumerator
mit
to_enum
oder seinem Alias
enum_for
oder einfach durch den Aufruf einer Iteratormethode ohne den eigentlich erwarteten Block:
e = [1..10].to_enum # Nutzt Range.each
e = "test".enum_for(:each_byte) # Nutzt String.each_byte
e = "test".each_byte # Nutzt String.each_byte
Enumerator
-Objekte sind
Enumerable
-Objekte mit einer Methode
each
, die auf einer anderen Iteratormethode eines anderen Objekts aufbaut. Neben dem Zweck, ein
Enumerable
-Proxy-Objekt zu sein, verhält sich ein Enumerator auch noch wie ein externer Iterator. Um die Elemente einer Collection mithilfe eines externen Iterators zu erhalten, rufen Sie einfach wiederholt
next
auf, bis eine
StopIteration
geworfen wird. Der Iterator
Kernel.loop
fängt
StopIteration
für Sie. Nachdem
next
die Exception
StopIteration
geworfen hat, wird ein trotzdem folgender erneuter Aufruf im Allgemeinen eine neue Iteration beginnen, wenn davon ausgegangen werden kann, dass die zugrunde liegende Iteratormethode eine wiederholte Iteration erlaubt (Iteratoren, die aus einer Datei lesen, erlauben das zum Beispiel nicht). Wenn wiederholte Iterationen möglich sind, können Sie einen externen Iterator noch vor dem Auslösen von
StopIteration
zurücksetzen, indem Sie
rewind
aufrufen:
"Ruby".each_char.max # => "y"; Enumerable-Methode von Enumerator
iter = "Ruby".each_char # Erzeugt einen Enumerator
loop { print iter.next } # Ausgabe "Ruby"; Verwendung als externer Iterator
print iter.next # Ausgabe "R": Iterator beginnt automatisch neu
iter.rewind # Setze Iterator zurück
print iter.next # Gibt "R" erneut aus
Mit einem beliebigen Enumerator
e
können Sie einen neuen Enumerator über
e.with_index
erhalten. Wie der Name impliziert, gibt dieser neue Enumerator zusammen mit dem Wert, den der ursprüngliche Enumerator zurückgeben würde, einen Index heraus (oder einen Iterationswert):
# Ausgabe "0:R\n1:u\n2:b\n3:y\n"
"Ruby".each_char.with_index.each {|c,i| puts "#{i}:#{c} }
Die Klasse
Enumerable::Enumerator
definiert eine Methode
to_splat
, was bedeutet, dass Sie einen Enumerator mit einem führenden Asterisk versehen können, um ihn in einzelne Werte für den Methodenaufruf oder parallele Zuweisungen zu »expandieren«.
9.5.1.3 Collections sortieren
Eine der wichtigsten Methoden von
Enumerable
ist
sort
. Es wandelt die
Weitere Kostenlose Bücher