Werbung einblenden Werbung ausblenden


Home / Tutorials / Perl Handbuch / assoziativen Arrays (Hashes)

einem Hash Werte zuweisen
auf einzelne Elemente eines Hashs zugreifen
den Inhalt eines Hashs vollständig auslesen
die Elemente eines Hashs auslesen - value Funktion
den Inhalt eines Hashs sortieren - sort

festellen, ob ein bestimmtes Element im Hash vorhanden ist - exists/grep
einzelne Elemente eines Hashs löschen - delete

einem Hash Werte zuweisen

Bei einem "gewöhnlichen" Array ist der Index eine Zahl, die bei der Zuweisung von Werten automatisch hochgezählt wird. Bei Hashes dagegen werden die Elemente nicht durchnummeriert, sondern jedes Element erhält eine Zeichenkette, einen Key (Schlüssel). Über diesen Key kann das Element dann angesprochen werden.
Das heißt, der Index ist hier eine Zeichenkette.
Auch das Einspeisen von Werten ist bei Hashes komplizierter und funktioniert so:

%banane=("Ehmann"=>"Andres","Maier"=>"Erich","Üzgür"=>"Yasemin",
"Mahmoodzadeh"=>"Shokufeh","Rodriguez"=>"Enrique");


Ehmann, Maier, Üzgür, Mahmoodzadeh, Rodriguez sind die Keys.
Der Pfeil ist hier nichts anderes als ein Komma, und soll die ganze Geschichte didaktisch geschickt aufbereiten.
Es funktioniert aber auch so:

%banane=("Ehmann","Andres",Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");


Wichtig! Hashes haben ein % Zeichen und kein @ Zeichen.

auf einzelne Elemente eines Hashs zugreifen

Auf ein einzelnes Element eines Hashs wird über den Schlüssel zugegriffen:

print $banane{'Ehmann'};

Ehmann ist hier der Schlüssel zu dem Element (Wert) Andres.
Es gibt einen Unterschied zum "gewöhnlichen" Array. Der Schlüssel ist von einer geschweiften Klammer umschlossen und nicht von einer eckigen.
Die Anführungstriche, doppelt oder einfach, sollten immer gesetzt werden, weil Perl sonst zwischen einem eventuellen reservierten Wort (split, push, pop etc. ) und einer Zeichenkette nicht unterscheiden kann. Weiter sind die Anführungsstriche auch dann notwendig, wenn der Schlüssel ein Leerzeichen hat.

den Inhalt eines Hashs vollständig auslesen

Es gibt unterschiedliche Möglichkeiten, den Inhalt eines Hashs auszulesen.
Hier werden drei Varianten vorgestellt.

1. Variante: foreach (keys(%banane))

%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
foreach (keys(%banane))
{
  print "Der Schlüssel ist $_ und der Wert dazu ist $banane{$_} \n";
}

Mit

@schluessel=keys(%banane);

erhält der Array @schluessel alle Schlüssel des Hashs %banane. Die einzelnen Elemente des Arrays @schluessel können dann mit einer foreach Schleife ausgelesen werden, siehe Funktionen zur Bearbeitung von Arrays.
Da kein Wert angegeben wurde, werden die einzelnen Elemente in der Sondervariablen $_ gespeichert.
Das sind dann die Schlüssel (Ehmann, Maier, Üzgür, Mahmoodzadeh, Rodriguez). Die Schlüssel wiederum werden in den Hash eingesetzt: $banane{'Ehmann'}, $banane{'Maier'} , $banane{'Mahmoodzadeh'} etc.

2. Variante: die Schlüssel an eine Variable übergeben

%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
foreach $himbeere(keys(%banane))
{
  print "Der Schlüssel ist $himbeere und der Wert dazu ist $banane{$himbeere} \n";
}

Das führt zum gleichen Ergebnis, hat aber nichts mit Hash zu tun, sondern eher damit, wie ein Array ausgelesen wird.

3. Variante: while Schleife und Funktion each

%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
while(($schluessel,$wert)=each(%banane))
{
  print "Der Schlüssel ist $schluessel und der Wert dazu ist $wert \n";
}

While läuft so lange, wie der Hash noch Werte hat (nicht 0 oder undef).
Wenn der Hash keine Werte mehr hat, liefert each undef, was die while Schleife zum Abbruch bringt.
Each wiederum bricht den Hash auf und liefert zwei Werte, den Schlüssel und den Wert. Eigentlich liefert each nur einen Array mit zwei Elementen.
Dieser Array kann dann aber an eine Liste übergeben werden:

@banane=("Ehmann","Maier","Üzgür","Mahmoodzadeh","Rodriguez");
($erster_Name,$zweiter_Name,$dritter_Name,$vierter_Name,$fuenfter_Name)=@banane;
print "$erster_Name und $zweiter_Name und $dritter_Name etc. ";

Der Array Banane wird also an eine Liste übergeben.

die Elemente eines Hashs auslesen - value Funktion

Zum Auslesen der Elemente (Werte) eines Hashs wird die value Funktion verwendet:

%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
foreach $himbeere(values(%banane))
{
  print "Der Wert ist $himbeere\n";
}

Das Programm setzt Andres, Erich, Yasemin, etc. auf den Schirm, also die Elemente (Werte).

Eine kürzere Schreibweise:

%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
@kirsche=values(%banane);
print @kirsche;
bzw. für keys
@kiwis=keys(%banane);

Mit values erhalten wir einen Array (@kirsche) mit allen Werten des assoziativen Arrays.
Mit keys(%banane); erhalten wir einen Array (@kiwis) mit allen Schlüsseln des assoziativen Arrays.

den Inhalt eines Hashs sortieren - sort
%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
@kirsche=values(%banane);
print @kirsche;

Da sollte jetzt eigentlich Andres, Erich, Yasemin, Shokufeh, Enrique rauskommen, denn dies ist die Reihenfolge,
in der die Werte abgespeichert sind.
Tatsächlich erhalten wir: Andres, Enrique, Erich, Yasemin, Shokufeh. Ein assoziativer Array (hash) ist eine ungeordnete Liste, das heißt, man hat keinerlei Einfluss auf die Reihenfolge der Ausgabe.

Ähnlich enttäuschend verläuft der folgendeTest:

%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
@kirsche=keys(%banane);
print @kirsche;

Anstelle "Ehmann, Maier, Üzgür, Mahmoodzadeh, Rodriguez" kommt hier "Ehmann, Rodriguez, Maier, Üzgür, Mahmoodzadeh" raus.
Besonders Pfiffige sind jetzt wahrscheinlich der Meinung, das liegt nur an den keys und values Funktionen und das liefert die korrekte Reihenfolge:

%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
while(($schluessel,$wert)=each(%banane))
{
  print "Der Schlüssel ist $schluessel und der Wert dazu ist $wert \n";
}

Die Reihenfolge der Datenausgabe entspricht aber auch hier nicht der Eingabe.

Wir erinnern uns an den sort Befehl und sortieren jetzt:

%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
@banane=sort(keys(%banane);
foreach $himbeere(@banane))
{
  print "Der Schlüssel ist $himbeere und der Wert ist $banane{$himbeere} \n";
}

Jetzt werden die Werte alphabetisch nach Nachnamen sortiert. Damit haben wir zwar immer noch nicht die Reihenfolge, in der die Daten ursprünglich eingegeben wurden, aber immerhin sind sie jetzt alphabetisch geordnet. Für die meisten Probleme der Praxis reicht das. Weiter zeigt das Beispiel, dass der hash %banane mit dem @banane nichts zu tun hat. Das sind zwei völlig voneinander unabhängige Variable, die sich auch nicht bekriegen.

festellen, ob ein bestimmtes Element im Hash vorhanden ist

Ist der Name Ehmann in dem folgenden Hash vorhanden?

%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
if(exists($banane{'Ehmann'}))
{
   print "Diesen Namen gibt es in dem Hash tatsächlich";
}
else
{
  print "Never heard of. Please call 11880";
}

Ergebnis:
Diesen Namen gibt es in dem Hash tatsächlich

Alternativ könne man das Problem auch mit grep lösen.

%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
@kirsche=keys(%banane);
@kiwi=grep(/Ehmann/,@kirsche);
if ($kiwi[0] ne "")
{
  print "Diesen Namen gibt es in dem Hash tatsächlich";
}
else
{
  print "Never heard of. Please call 11880";
}

Der letzte Ansatz ist der Leistungsfähigere, da grep regular expressions unterstützt.
Grep schaut nach, ob ein bestimmter Typ von Text in einem Array enthalten ist. Sehr sinnvoll ist die Anwendung von grep zum Beispiel bei Suchmaschienen siehe Suchmaschine in festen Ordnern.
Für einfache Fälle ist die exists Funktion brauchbar.

einzelne Elemente eines Hashs löschen
%banane=("Ehmann","Andres","Maier","Erich","Üzgür","Yasemin",
"Mahmoodzadeh","Shokufeh","Rodriguez","Enrique");
delete($banane{'Maier'});
foreach $himbeere(keys(%banane))
{
print "Nachname:$himbeere und Vorname $banane{'$himbeere'}\n";
}
vorhergehendes Kapitel