next up previous contents index
Search Next: Auf Hashelemente zugreifen Up: Arrays und Hashtabellen Previous: Iteratoren für Arrays   Contents   Index

Hashtabellen erzeugen und verwalten

Eine Hashtabelle (in Smalltalk: Dictionary) ist ein Sammlung von Schlüssel-Wert-Paaren. Für ihre Erzeugung gibt es folgende Möglichkeiten:

h = {"a"=>1, "b"=>2, "c"=>3}
i = {"d"=>4}
i["e"]  #-> nil
j = Hash.new("gibt's nicht")
j["e"]  #-> "gibt's nicht"
i.update(h)
i       #-> {"d"=>4, "a"=>1, "b"=>2, "c"=>3}
i.replace(h)
i       #-> {"a"=>1, "b"=>2, "c"=>3}

Hash-Literale zur Initialisierung von Hashes werden in geschweifte Klammern {} geschrieben. Der Zugriff auf die Hashelemente erfolgt aber immer, indem der Schlüssel des zu suchenden Wertes in eckige Klammern [] gesetzt wird.

Das Argument der new-Methode wird als Defaultwert genutzt. Sollte ein Schlüssel vom Hash angefordert werden, der nicht enthalten ist, wird der Defaultwert zurückgegeben.


\epsfig{height=36pt,file=images/chan.eps}Ab Ruby 1.7.2 (10.12.2001) kann als Argument auch ein Block übergeben werden, der ausgewertet wird, wenn die Hashtabelle das gewünschte Element noch nicht enthält.

euro = Hash.new { |h, dm| h[dm] = dm*1.95583 }
euro[100]   #-> 195.583

In älteren Ruby-Versionen kann man sich mit ||= behelfen:

euro = Hash.new
def getEuro(dm)
  euro[dm] ||= dm*1.95583
end
\epsfig{height=10pt,file=images/ruby.eps}

Wie bei Arrays wird mit clear die Hashtabelle geleert. Die Methode update fügt die Inhalte der übergebenen Hashtabelle ein, wobei die Werte von schon vorhandenen Schlüsseln ersetzt werden.

h1 = {"a"=>100, "b"=>110}   #-> {"a"=>100, "b"=>110}
h2 = {"b"=>120, "c"=>130}   #-> {"b"=>120, "c"=>130}
h1.update(h2)     #-> {"a"=>100, "b"=>120, "c"=>130}

replace ersetzt den Inhalt der vorhandenen Hashtabelle. Dabei werden alle Schlüssel-Wert-Paare ersetzt!


\epsfig{height=36pt,file=images/chan.eps}Hashtabellen können beliebige Objekte als Werte enthalten, die Schlüssel sollten eine gewisse Beständigkeit besitzen: Solange sie als Schlüssel verwendet werden, sollte sich der Wert ihrer hash-Methode nicht ändern, um einen dauerhaften Zugriff auf die Hashelemente zu gewährleisten.

Daher muss man insbesondere bei Arrays und Hashtabellen vorsichtig sein, wenn man sie als Schlüssel verwenden möchte, da sich ihr hash-Wert bei Manipulationen ihrer Elemente ändert.

a = [1, 2, 3]            #-> [1, 2, 3]
a.hash                   #-> 25
h = { a=>"gefunden" }
h[a]                     #-> "gefunden"
a.shift
a.hash                   #-> 5
h[a]                     #-> nil
h.rehash
h[a]                     #-> "gefunden"

Mit rehash werden alle in der Hashtabelle gespeicherten Hashwerte neu berechnet, was ziemlich viel Rechenzeit kosten kann, wenn die Hashtabelle größer wird. \epsfig{height=10pt,file=images/ruby.eps}

Bei den besonders häufig als Schlüssel verwendeten Strings setzt Ruby automatisch eine Kopie des Schlüsselstrings in die Hashtabelle ein, um dieses Problem zu vermeiden.

s = "foo"
s.hash                 #-> 876516207
hash = { s => "bar" }  #-> {"foo" -> "bar"}
s[1,2] = "uu"
s                      #-> "fuu"
s.hash                 #-> 876922107
hash                   #-> {"foo" -> "bar"}

Ein elementweiser Vergleich von Hashtabellen ist mit der Methode == möglich.

{1=>2, 3=>4} == {3=>4, 1=>2} #-> true
{1=>2, 3=>4} == {1=>2, 3=>5} #-> false
{1=>2, 3=>4} == {1=>2, 2=>4} #-> false
Ruby prüft, ob beide Hashes dieselben Schlüssel beinhalten (selber Wert aller Schlüssel) und ob unter jedem Schlüssel derselbe Wert (Gleichheit) gespeichert ist.

Die Methode invert erzeugt eine Hashtabelle, bei der Schlüssel und Werte vertauscht sind.

h = {"a"=>1, "b"=>2}  #-> {"a"=>1, "b"=>2}
h.invert              #-> {1=>"a", 2=>"b"}

Falls zwei Werte gleich sind, so überschreibt Ruby stillschweigend beginnend von links.

{"a"=>1, "b"=>1}.invert   #-> {1=>"b"}

Die Methoden keys und values dienen der Abfrage aller Schlüssel bzw. aller Werte eines Hashes.

h = {"a"=>1, "b"=>2, "c"=>2}
h.keys               #-> ["a", "b", "c"]
h.values             #-> [1, 2, 2]
h.length             #-> 3
h.size               #-> 3

Für length gibt es wie immer die Alternative size.

Obwohl Hashtabellen ihre Elemente nicht anordnen, bietet Ruby für sie eine Methode sort an. Allerdings ist das Resultat ein (angeordnetes) Assoziationsarray, in dem die Einträge nach den Schlüsselwerten sortiert sind.

{"b"=>2, "a"=>1, "c"=>3}.sort
  #-> [["a", 1], ["b", 2], ["c", 3]]


next up previous contents index
Search Next: Auf Hashelemente zugreifen Up: Arrays und Hashtabellen Previous: Iteratoren für Arrays   Contents   Index
(C) 2002 by dpunkt.de, Armin Roehrl, Stefan Schmiedl, Clemens Wyss 2002-01-20