Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort des Fachgutachters
Einleitung
1 Einführung
2 Installation
3 Erste Schritte
4 Einführung in Ruby
5 Eine einfache Bookmarkverwaltung
6 Test-Driven Development
7 Rails-Projekte erstellen
8 Templatesystem mit ActionView
9 Steuerzentrale mit ActionController
10 Datenbankzugriff mit ActiveRecord
11 E-Mails verwalten mit ActionMailer
12 Nützliche Helfer mit ActiveSupport
13 Ajax on Rails
14 RESTful Rails und Webservices
15 Rails mit Plug-ins erweitern
16 Performancesteigerung
17 Sicherheit
18 Veröffentlichen einer Rails-Applikation auf einem Server
Ihre Meinung?

Spacer
 <<   zurück
Ruby on Rails 2 von Hussein Morsy, Tanja Otto
Das Entwickler-Handbuch
Buch: Ruby on Rails 2

Ruby on Rails 2
geb., mit DVD
699 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-89842-779-1
Online bestellenPrint-Version jetzt bestellen
* versandkostenfrei in (D) und (A)
Pfeil 4 Einführung in Ruby
  Pfeil 4.1 Was ist Ruby?
  Pfeil 4.2 Ruby-Code ausführen
  Pfeil 4.3 Grundlagen
  Pfeil 4.4 Zahlen
  Pfeil 4.5 Zeichenketten
  Pfeil 4.6 Symbole
  Pfeil 4.7 Reguläre Ausdrücke
  Pfeil 4.8 Arrays
  Pfeil 4.9 Hashes
  Pfeil 4.10 Datum und Zeit
  Pfeil 4.11 Module


Rheinwerk Computing - Zum Seitenanfang

4.8 Arrays  Zur nächsten ÜberschriftZur vorigen Überschrift

Arrays in Ruby haben Indizes vom Typ Integer. Der Index beginnt standardmäßig bei 0. Wenn Sie ein neues Array erzeugen, können Sie seine Größe über einen Parameter angeben, müssen das aber nicht, denn Arrays passen ihre Grösse dynamisch der zu speichernden Datenmenge an.

Ein Array kennt zu jedem Zeitpunkt seine aktuelle Größe, so dass wir uns nicht darum kümmern müssen, diesen Wert aufwendig zu ermitteln, sondern wir können ihn jederzeit ganz einfach abfragen. Die Klasse Array stellt eine Vielzahl von Methoden zur Verfügung, um auf Arrays zuzugreifen, sie zu durchsuchen, sie miteinander zu verknüpfen oder anderswie mit ihnen zu arbeiten.


Rheinwerk Computing - Zum Seitenanfang

Ein Array erzeugen  Zur nächsten ÜberschriftZur vorigen Überschrift

[]

Die Klassenmethode [] erzeugt ein neues Array. Es gibt 3 Möglichkeiten, diese Methode zu nutzen und ihr die Werte des Arrays zu übergeben:

>> a1 = ["a","b","c","d"]
=> [a, b, c, d]
>> a2 = Array.[]("a","b","c","d")
=> [a, b, c, d]
>> a3 = Array["a","b","c","d"]
=> [a, b, c, d]

new

Sie können auch über die Methode new ein neues Array erzeugen. Der Methode new können Sie keinen, einen oder zwei Parameter übergeben. Über den ersten Parameter können Sie die Größe des Arrays (Anzahl der Elemente) festlegen und über den zweiten den Wert dieser Elemente:

>> a4 = Array.new
=> []
>> a5 = Array.new(2)
=> [nil, nil]
>> a6 = Array.new(2, "test")
=> ["test", "test"]

Im letzten Beispiel sieht es so aus, als ob in dem Array a6 zwei verschiedene Objekte abgelegt wurden. Dem ist aber nicht so. Die beiden Werte verweisen auf das gleiche Objekt. Sprich, wenn Sie eines der Elemente verändern, wirkt sich das auf alle Elemente aus.

>> a6[0].upcase!
=> "TEST"
>> a6
=> ["TEST", "TEST"]

Block verwenden

Um diese Situation zu vermeiden, können Sie beim Erzeugen des Arrays einen Block verwenden, denn der Block wird für jedes Element neu ausgeführt und erzeugt deshalb voneinander unabhängige Objekte:

>> a7 = Array.new(2) {"test"}
=> ["test", "test"]
>> a7[0].upcase!
=> "TEST"
>> a7
=> ["TEST", "test"]

Rheinwerk Computing - Zum Seitenanfang

Auf Arrayelemente zugreifen  Zur nächsten ÜberschriftZur vorigen Überschrift

Um ein Arrayelement anzulegen und um auf ein Arrayelement zuzugreifen, nutzen Sie die beiden Methoden [] und +[]=+. Beiden Methoden können Sie als Index einen Integer-Wert übergeben oder zwei Integer-Werte, die dann den Startpunkt und eine Länge repräsentieren, oder Sie können den Methoden einen Bereich übergeben. Ein negativer Index zählt vom Ende des Arrays. Auf das letzte Element eines Arrays kann z. B. mit dem Index »-1« zugegriffen werden.

at

Die Instanzmethode at funktioniert genauso wie der Zugriff über [] mit einem Parameter, ist jedoch dadurch schneller in der Ausführung:

>> a = ["Januar", "Februar", "Maerz", "April"]
=> ["Januar", "Februar", "Maerz", "April"]
>> a[1]
=> "Februar"
>> a.at(-1)
=> "April"
>> a[4]
=> nil
>> a[1,2]
=> ["Februar", "Maerz"]
>> a[3] = "Mai"
=> "Mai"
>> a[-1]
=> "Mai"
>> a
=> ["Januar", "Februar", "Maerz", "Mai"]

slice

Die Methode slice ist ein Alias für die Methode []:

>> a.slice(2)
=> "Maerz"
>> a.slice(1,2,3)
=> ["Februar", "Maerz", "Mai"]

Wenn Sie ein Element an einer Position über die Länge des Arrays hinaus einfügen, passt das Array automatisch seine Größe an, sprich, es wird größer und setzt eventuelle nicht besetzte Positionen dazwischen auf »nil«. Gleiches passiert, wenn Sie für einen Bereich mehr Werte übergeben als eigentlich für den Bereich möglich wären:

>> a = ["M", "HH", "B"]
=> ["M", "HH", "B"]
>> a[1..2] = ["TR", "D"]
=> ["TR", "D"]
>> a
=> ["M", "TR", "D"]
>> a[1..2] = ["TR", "D", "K"]
=> ["TR", "D", "K"]
>> a
=> ["M", "TR", "D", "K"]
>> a[10] = "HB"
=> "HB"
>> a
=> ["M", "TR", "D", "K", nil, nil, nil, nil, nil, nil, "HB"]

Wenn Sie einem Array-Element wiederum ein Array zuweisen, wird dieses in das vorhandene Array verschachtelt. Anders verhält es sich, wenn Sie einem Bereich in einem Array ein Array übergeben. Dann werden die Elemente des übergebenen Arrays an den Positionen des angegebenen Bereichs eingefügt:

>> a = ["Birne", "Apfel", "Banane"]
=> ["Birne", "Apfel", "Banane"]
>> a[0] = ["Paprika", "Blumenkohl"]
=> ["Paprika", "Blumenkohl"]
>> a
=> [["Paprika", "Blumenkohl"], "Apfel", "Banane"]
>> a[1..2] = ["Ananas", "Trauben", "Datteln"]
=> ["Ananas", "Trauben", "Datteln"]
>> a
=> [["Paprika", "Blumenkohl"], "Ananas", "Trauben", "Datteln"]

first, last

Die Methoden first und last liefern das erste bzw. letzte Element eines Arrays. Wenn das Array leer ist, geben sie nil zurück:

>> a = ["Birne", "Apfel", "Banane"]
=> ["Birne", "Apfel", "Banane"]
>> a.first
=> "Birne"
>> a.last
=> "Banane"

Ruby kennt eine Kurzschreibweise, um ein Array mit Zeichenketten aufzubauen:

>> %w[Birne Apfel Banane]
=> ["Birne", "Apfel", "Banane"]

Durch das vorangestellte %w sparen Sie die Eingabe der Hochkommata und der Kommata als Trennzeichen zwischen den einzelnen Werten.

Mehrere Elemente auslesen

Wir haben eben gesehen, dass es möglich ist, durch Übergabe eines Bereichs oder durch die Definition eines Startpunktes und einer bestimmten Länge an die Methode [] mehrere Elemente eines Arrays gleichzeitig auszulesen. Die Methode values_at bietet uns noch weitere Möglichkeiten, mehrere Elemente gleichzeitig auszulesen. Als Parameter empfängt sie eine Liste von Indizes. Die Methode values_at kommt immer dann zum Einsatz, wenn die auszulesenden Elemente nicht zusammenstehen, also immer dann, wenn die Angabe eines Bereichs nicht mehr ausreicht:

>> a = [1,2,3,4,5,6,7,8,9]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
>> a.values_at(2,5,8)
=> [3, 6, 9]
>> a.values_at(0,2..5,8)
=> [1, 3, 4, 5, 6, 9]

Die Methode values_at hieß in älteren Versionen von Ruby indices (Alias indexes). Von der aktuellen Ruby-Version werden diese beiden Methoden nicht mehr unterstützt.


Rheinwerk Computing - Zum Seitenanfang

Auf die Länge eines Arrays zugreifen  Zur nächsten ÜberschriftZur vorigen Überschrift

length, size

Die Methode length und ihr Alias size liefern die Anzahl der Elemente in einem Array zurück. Wie wir das von ähnlichen Methoden anderer Programmiersprachen kennen, ist die Anzahl um einen Wert höher als der letzte Index in dem Array:

>> a = %w[rot gelb gruen]
=> ["rot", "gelb", "gruen"]
>> a.length
=> 3
>> a.size
=> 3

nitems

Die Methode nitems zählt auch die Elemente eines Arrays, mit Ausnahme der nil-Elemente:

>> a = ["rot", nil, nil, "gelb", nil, "gruen"]
=> ["rot", nil, nil, "gelb", nil, "gruen"]
>> a.length
=> 6
>> a.nitems
=> 3

Rheinwerk Computing - Zum Seitenanfang

Arrays vergleichen  Zur nächsten ÜberschriftZur vorigen Überschrift

Modul Comparable

Arrays miteinander zu vergleichen, ist eine knifflige Angelegenheit. Nicht so, wenn man das Modul Comparable dazu nutzt. Die Methoden eines Moduls kann man in anderen Klassen nutzen, indem man das Modul inkludiert (Mehr Informationen zu Module siehe Abschnitt 4.11):

class Array
  include Comparable
end

a = [5, 6, 7]
b = [5, 6, 7, 8]
c = [5, 6, 7]
if a < b
  puts "a < b"
end
if a == c
  puts "a == c"
end

# => a < b
# => a == c

Rheinwerk Computing - Zum Seitenanfang

Ein Array sortieren  Zur nächsten ÜberschriftZur vorigen Überschrift

sort

Die einfachste Art und Weise, ein Array zu sortieren, ist, die Methode sort wie folgt zu benutzen:

>> woerter = %w(RailsAir ist eine erfolgreiche Airline)
=> ["RailsAir", "ist", "eine", "erfolgreiche", "Airline"]
>> woerter.sort
=> ["Airline", "RailsAir", "eine", "erfolgreiche", "ist"]
>> woerter
=> ["RailsAir", "ist", "eine", "erfolgreiche", "Airline"]
>> woerter.sort!
=> ["Airline", "RailsAir", "eine", "erfolgreiche", "ist"]
>> woerter
=> ["Airline", "RailsAir", "eine", "erfolgreiche", "ist"]

Auch für Methoden der Klasse Array gilt: Methoden, die mit einem Ausrufezeichen enden, verändern das Ausgangsobjekt.

Die Methode sort ist nur dann fehlerfrei einsetzbar, wenn alle Elemente innerhalb des Arrays vom gleichen Datentyp sind. Anderenfalls liefert sie einen TypeError zurück:

>> a = ["zeichen", "zahl", 3]
=> ["zeichen", "zahl", 3]
>> a.sort
ArgumentError: comparison of String with 3 failed
	from (irb):2:in 'sort'
	from (irb):2

Mit einem Block aufrufen

Das können Sie verhindern, indem Sie in einem solchen Fall die Methode sort mit einem Block aufrufen und in diesem Block jedes Element in den gleichen Datentyp umwandeln (z. B. mit der Methode to_s in einen String):

>> a.sort {|x,y| x.to_s <=> y.to_s}
=> [3, "zahl", "zeichen"]

Die Sortierung erfolgt nach der Umwandlung in einen String auf ASCII-Basis.

Natürlich haben Sie Recht: Bei diesem Beispiel handelt es sich um ein rein theoretisches Beispiel, da es nicht viel Sinn macht, ein Array, das Elemente unterschiedlicher Datentypen enthält, zu sortieren. Trotzdem möchten wir Ihnen noch kurz erläutern, was da genau passiert:

Der Block liefert bei jedem Aufruf -1, 0 oder 1 zurück. Im Falle von -1, was bedeutet, dass x kleiner y ist, werden die beiden Elemente vertauscht. Das bedeutet wiederum, dass wenn wir ein Array in absteigender Reihenfolge sortieren möchten, wir einfach nur die Variablen innerhalb des Vergleichs vertauschen müssen:

>> a.sort {|x,y| y.to_s <=> x.to_s}
=> ["zeichen", "zahl", 3]

sort_by

In den neueren Versionen von Ruby enthält das Modul Enumerable die Methode sort_by . Dieses Modul ist standardmäßig in der Klasse Array inkludiert.

Die Methode sort_by setzt das ein, was Perl-Programmierer unter dem Begriff »Schwartzian Transformation« kennen (nach Randal Schwartz). Die Sortierung beruht nicht auf den zu sortierenden Elementen selbst, sondern es wird eine Art Funktion zum Sortieren angewendet. Dieser Lösungsansatz birgt zwei Probleme: Zum einen wirkt der Code umständlich, und zum anderen ergeben sich aus jedem Aufruf mehrere Plattenzugriffe, von denen jeder eine aufwendige Aktion darstellt, und der Block wird öfter als einmal aufgerufen.

Mit der sort_by -Methode kann man beide Probleme lösen. Jeder Schlüssel wird nur noch einmal berechnet und dann intern in einem Schlüssel-Daten-Paar abgespeichert. Bei kleineren Arrays könnte das die Leistungsfähigkeit verringern, aber der Code ist allemal viel schöner, und das sollte es uns wert sein.

Es gibt standardmäßig keine Methode sort_by!, aber Sie können natürlich jederzeit eine solche Methode definieren.

Nach mehreren Attributen sortieren

Aber was ist, wenn wir ein Array über mehr als ein Attribut sortieren müssen, wie z. B. Name, Alter und Größe? Sie können selbstverständlich nach mehreren Attributen, egal nach welchen, sortieren:

list = list.sort_by {|x| [x.name, x.age, x.height] }

Rheinwerk Computing - Zum Seitenanfang

Ein Array zufällig sortieren  Zur nächsten ÜberschriftZur vorigen Überschrift

Manchmal möchten wir die Elemente in einem Array in eine zufällige Reihenfolge bringen. Sei es z. B. für ein Online-Kartenspiel oder um in einem Gewinnspiel den Usern die Fragen in einer zufälligen Reihenfolge anzuzeigen.

rand

Um das Problem zu lösen, steht uns die Methode rand aus dem Modul Kernel zur Verfügung, die uns eine zufällige Zahl liefert:

class Array
  def randomize
    self.sort_by { rand }
  end
end

x = [1, 2, 3, 4, 5]
puts x.randomize
# => [3, 4, 1, 5, 2]

Wenn wir ein Array-Element zufällig auswählen wollen, können wir das wie folgt lösen:

class Array
  def pick_random
    self[rand(self.length)]
  end
end

x = [1, 2, 3, 4, 5]
puts x.pick_random
# => 4

Rheinwerk Computing - Zum Seitenanfang

Nach Elementen in einem Array suchen  Zur nächsten ÜberschriftZur vorigen Überschrift

Manchmal wollen wir auf ein bestimmtes Element innerhalb eines Arrays genauso zugreifen wie auf ein Element innerhalb einer Datenbank. Die gute Nachricht: Es gibt mehrere Möglichkeiten, das zu tun. Alle die, die wir Ihnen hier vorstellen, sind im Modul Enumerable definiert, das von der Klasse Array inkludiert wird.

detect

Die Methode detect findet höchstens ein Element. Sie führt einen Block aus, an den die einzelnen Elemente der Reihe nach übergeben werden, und liefert den ersten Wert, auf den die Bedingung zutrifft, als Ergebnis zurück.

>> a = [5, 21, 9, 4, 1, 8]
=> [5, 21, 9, 4, 1, 8]
>> a.detect {|e| e % 2 == 0 }
=> 4
>> a.detect {|e| e % 7 == 0 }
=> 21

find, find_all, select

Die Methode find ist ein Alias der Methode detect . Die Methode find_all ist eine Variante der Methode find, die alle passenden Ergebnisse in einem Ergebnisarray zurückliefert. Die Methode select ist wiederum ein Alias der Methode find_all:

>> a.find {|e| e % 2 == 0}
=> 4
>> a.find_all {|e| e % 2 == 0}
=> [4, 8]
>> a.select {|e| e % 2 == 0}
=> [4, 8]

reject

Die Methode reject ist die Komplementärmethode zu select . Sie schließt alle Elemente aus, auf die die Bedingung im Block zutrifft. Die Methode reject!, die das Originalobjekt verändert, ist auch definiert:

>> a.reject {|e| e % 2 == 0 }
=> [5, 21, 9, 1]

grep

Die Methode grep setzt den Operator === ein, um jedes Element mit einem vorgegebenen Muster zu vergleichen. In ihrer einfachsten Form angewendet, liefert sie ein Array mit den übereinstimmenden Ergebnissen zurück. Das Muster kann außer einem regulären Ausdruck auch z. B. ein Bereich sein. Der Name grep kommt aus der Unix-Welt und steht in Bezug zu dem alten Editorbefehl g\/re\/p.

>> a = %w[taschenbuch buchhandlung buecherei buecher]
=> ["taschenbuch", "buchhandlung", "buecherei", "buecher"]
>> a.grep(/buch/)
=> ["taschenbuch", "buchhandlung"]

min, max

Die beiden Methoden min und max, die im Modul Enumerable definiert sind, können verwendet werden, um den Minimal- und Maximalwert innerhalb eines Arrays zu ermitteln. Den beiden Methoden können entweder keine Parameter oder ein Block übergeben werden. Übergibt man ihnen keinen Parameter, ermitteln sie den Minimal- bzw. Maximalwert der gegebenen Werte innerhalb des Arrays. Durch Übergabe eines Blocks können wir definieren, von welchem Attribut der Elemente im Array wir den Minimal- oder Maximalwert erhalten möchten:

>> a = %w[Schottland Deutschland Luxemburg Spanien]
=> ["Schottland", "Deutschland", "Luxemburg", "Spanien"]
>> a. min
=> "Deutschland"
>> a.max
=> "Spanien"
>> a.min {|x,y| x.length <=> y.length}
=> "Spanien"
>> a.max {|x,y| x.length <=> y.length}
=> "Deutschland"

Angenommen, wir wollten den Index des Minimal- oder Maximalwertes ermitteln, würden wir der Methode index das Ergebnis der Methoden min oder max als Parameter übergeben. Bezugnehmend auf obiges Beispiel bedeutet das konkret:

>> a.index(a.min)
=> 1
>> a.index(a.max)
=> 3

Die Methode index kann natürlich auf jedes beliebige Element eines Arrays angewendet werden. Sollte das übergebene Element innerhalb des Arrays nicht eindeutig sein, liefert die Methode den Index des ersten Vorkommens des Elementes zurück:

>> a.index("Schottland")
=> 0
>> a.index("Luxemburg")
=> 2

Rheinwerk Computing - Zum Seitenanfang

Differenz zwischen zwei Arrays bestimmen  Zur nächsten ÜberschriftZur vorigen Überschrift

Dieses Problem lässt sich in Ruby sehr viel einfacher lösen als in den meisten anderen Programmiersprachen:

text = %w[hier sind die gesuchten Wörter Schottland Luxemburg]
vergleich = %w[die gesuchten Wörter sind hier nicht enthalten]
unbekannt = text - vergleich  # ["Schottland", "Luxemburg"]

Rheinwerk Computing - Zum Seitenanfang

nil-Werte aus einem Array entfernen  Zur nächsten ÜberschriftZur vorigen Überschrift

compact

Die Methode compact oder compact! entfernt nil -Elemente aus einem Array:

>> a = [7, 9, nil, 5, nil, 3, 1]
=> [7, 9, nil, 5, nil, 3, 1]
>> a.compact
=> [7, 9, 5, 3, 1]

Rheinwerk Computing - Zum Seitenanfang

Bestimmte Array-Elemente entfernen  Zur nächsten ÜberschriftZur vorigen Überschrift

delete_at

Es gibt viele Möglichkeiten, bestimmte Elemente aus einem Ruby-Array zu entfernen. Wenn Sie ein Element an einer bestimmten Position entfernen möchten, ist die Methode delete_at eine gute Wahl. Die Methode erwartet eine Index-Position als Parameter. Ist die übergebene Position außerhalb des Bereichs des Arrays, liefert die Methode nil zurück:

>> a =  [7, 9, 5, 3, 1]
=>  [7, 9, 5, 3, 1]
>> a.delete_at(3)
=> 3
>> a
=>  [7, 9, 5, 1]
>> a.delete_at(10)
=> nil

delete

Wenn wir alle Elemente mit einem bestimmten Wert aus einem Array entfernen möchten, kommt die Methode delete zum Einsatz. Sie liefert den Wert der gelöschten Elemente oder, sollte der übergebene Wert nicht existieren, nil zurück.

>> a = %w(Januar Februar Januar April Mai April Januar)
=> ["Januar", "Februar", "Januar", "April", "Mai", "April",
"Januar"]
>> a.delete("Januar")
=> "Januar"
>> a
=> ["Februar", "April", "Mai", "April"]

Der Methode delete können Sie auch einen Block übergeben. Das Besondere dabei ist, dass der Block nur dann ausgeführt wird, wenn der zu löschende Wert nicht innerhalb des Arrays gefunden wird:

>> a.delete("April") { "existiert nicht" }
=> "April"
>> a.delete("September") { "existiert nicht" }
=> "existiert nicht"

delete_if

Die Methode delete_if führt den Block für jedes Array-Element aus und löscht die Elemente, die die Bedingung im Block erfüllen. Da die Elemente aus dem Originalobjekt gelöscht werden, verhält sich delete_if ähnlich wie die Methode reject! . Trifft die Bedingung im Block auf keines der Elemente zu, liefert die Methode nil zurück:

>> texte = %w[newsletter spam gruesse angebote]
=> ["newsletter", "spam", "gruesse", "angebote"]
>> texte.delete_if {|x| x.length == 4 }
=> ["newsletter", "gruesse", "angebote"]

shift, pop

Die Methoden shift und pop löschen das erste bzw. letzte Element eines Arrays:

>> a = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
>> a.shift
=> 1
>> a
=> [2, 3, 4, 5]
>> a.pop
=> 5
>> a
=> [2, 3, 4]

clear

Schließlich können Sie mit der Methode clear alle Elemente aus einem Array löschen. Das können Sie auch erreichen, indem Sie der Arrayvariablen ein leeres Array zuweisen, aber die Methode clear ist effizienter:

>> a.clear
=> []

Rheinwerk Computing - Zum Seitenanfang

Ein Array umkehren  Zur nächsten ÜberschriftZur vorigen Überschrift

reverse

Nicht nur der Klasse String steht eine Methode reverse zur Verfügung, um eine Zeichenkette umzukehren, sondern auch die Klasse Array hat eine Methode reverse, um ein Array umzukehren:

>> tiere = %w[hund katze maus]
=> ["hund", "katze", "maus"]
>> tiere.reverse
=> ["maus", "katze", "hund"]

Rheinwerk Computing - Zum Seitenanfang

Doppelte Einträge aus einem Array löschen  Zur nächsten ÜberschriftZur vorigen Überschrift

uniq

Wenn Sie doppelte Einträge aus einem Array löschen möchten, können Sie das mit Hilfe der Methode uniq oder uniq! tun. Die Methode liefert ein Array ohne doppelte Einträge zurück. Befindet sich kein doppelter Eintrag in dem Array, liefert uniq nil zurück:

>> a = ["a", "b", "a", "c", "c", "d"]
=> ["a", "b", "a", "c", "c", "d"]
>> a.uniq
=> ["a", "b", "c", "d"]

Rheinwerk Computing - Zum Seitenanfang

Iteratoren  topZur vorigen Überschrift

Ruby stellt uns eine Reihe von Methoden zur Verfügung, mit denen wir über ein Array iterieren können (Iteratoren).

each

Der Standard-Iterator der Klasse Array ist die Methode each . Die Methode erwartet einen Block als Übergabeparameter, den sie für jedes Element ausführt und dem sie das Element selbst als Parameter übergibt:

>> a = [ "a", "b", "c" ]
=> ["a", "b", "c"]
>> a.each {|x| print x, " ++ " }
a ++ b ++ c ++ => ["a", "b", "c"]

reverse_each

Schneller als reverse.each

Ein anderer nützlicher Iterator ist die Methode reverse_each, die in umgekehrter Reihenfolge als die Methode each über ein Array iteriert. Um das gleiche Ziel zu erreichen, könnten Sie auch zuerst die Methode reverse und dann die Methode each anwenden, die Methode reverse_each ist aber wesentlich schneller:

>> aussage = %w(Die ist ein Beispiel)
=> ["Dies", "ist", "ein", "Beispiel"]
>> str = ""
=> ""
>> aussage.reverse_each { |w| str += "#{w} "}
=> ["Dies", "ist", "ein", "Beispiel"]
>> str
=> "Beispiel ein ist Dies"

each_index

Um nur über die Indizes eines Arrays zu iterieren, steht die Methode each_index zur Verfügung, die dem Block den aktuellen Index als Parameter übergibt:

>> a = [ "a", "b", "c" ]
=> ["a", "b", "c"]
>> a.each_index {|x| print x, " ++ " }
0 ++ 1 ++ 2 ++ => ["a", "b", "c"]

each_with_index

Der Iterator each_with_index ist eine Kombination aus der Methode each und der Methode each_index . Dem Block werden zwei Parameter, das Element selbst und sein Index, übergeben:

>> a = ["a", "b", "c"]
=> ["a", "c", "c"]
>> a.each_with_index do |x,i|
>> puts "Element #{x} ist #{i}"
>> end
Element 0 ist a
Element 1 ist b
Element 2 ist c
=> ["a", "b", "c"]

map

Wir können aber auch mit der Methode map oder ihrem Synonym collect über ein Array iterieren. Den Methoden können wir einen Block übergeben, der für jedes Element aus dem Array ausgeführt wird. Als Ergebnis wird wieder ein Array zurückgeliefert. In unserem Beispiel möchten wir die in einem Array gespeicherten Preise um 10 % erhöhen:

preise = [2.5, 5.6, 12.10]
preise.map {|preis| preis *1.1}
# => [2.75, 6.16, 13.31]

Mit der Methode map oder collect können Sie auch nur bestimmte Attribute von Objekten aus einem Array ausgeben:

class Product
  attr_accessor :name
  attr_accessor :price

  def initialize(params)
    @name = params[:name]
    @price = params[:price]
  end
end

product1 = Product.new(:name => 'iMac', :price=>1400)
product2 = Product.new(:name => 'MacBook', :price=>999)
product3 = Product.new(:name => 'iPhone', :price=>499)
products = [product1, product2, product3]

p products.map{|product| product.name}
# => ["iMac", "MacBook", "iPhone"]

any?

Mit der Methode any?, die true oder false zurückliefert, können wir abfragen, ob es ein oder mehrere Elemente in einem Array gibt, die eine bestimmte Bedingung erfüllen:

p products.any?{|product| product.price < 1000}
# => true

all?

Mit der Methode all?, die ebenfalls true oder false zurückliefert, können wir abfragen, ob alle Elemente eine bestimmte Bedingung erfüllen:

p products.all?{|product| product.price < 1000}
# => false


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
 <<   zurück
  Zum Katalog
Zum Katalog: Ruby on Rails 2
Ruby on Rails 2
Jetzt bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Ruby on Rails 3.1






 Ruby on Rails 3.1


Zum Katalog: Responsive Webdesign






 Responsive Webdesign


Zum Katalog: Suchmaschinen-Optimierung






 Suchmaschinen-
 Optimierung


Zum Katalog: JavaScript






 JavaScript


Zum Katalog: Schrödinger lernt HTML5, CSS3 und JavaScript






 Schrödinger lernt
 HTML5, CSS3
 und JavaScript


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de