Perl - Hashes unter Bewahrung der Reihenfolge

In Perl ist ein Hash (andere Sprachen nennen diese Datenstruktur gern auch "Dictionary") eine Zuordnung von Schlüssel=>Wert Paaren. Aufgrund der internen Implementierung eines effizienten Lookups von Schlüsseln geht jedoch die Reihenfolge des Einfügens verloren. Wird über die Schlüssel bzw. Schlüssel/Wert Paare iteriert, so ist somit keine einfache Voraussage über die Ausgaberreihenfolge möglich. Dazu ein Beispiel. Folgendes Codefragment legt einen Hash an und füllt ihn mit Werten:
# file hashtest.pl
my %hash = (
    'Feld1' => 'Wert1',
    'Auch Ein Key' => 'mit Daten',
    'Feld2' => 'Wert2',
    'Feld3' => 'Wert3',
);
 
while ( my($key,$value) = each %hash) {
    print "$key => $value\n";
}
Führt man diesen Code aus so erhält man:
$ perl hashtest.pl 
Feld3 => Wert3
Auch Ein Key => mit Daten
Feld2 => Wert2
Feld1 => Wert1
Die Reihenfolge der Ausgabe des Iterierens entspricht also tatsächlich nicht der Reihenfolge des Einfügens. Da es aber manchmal wünschenswert ist, dieselbe Reihenfolge zu erhalten, exisitiert mit dem Modul Tie::IxHash eine Alternative. Das Modul findet sich wie üblich über CPAN, Debian oder Ubuntu Benutzer können es mit dem Paket libtie-ixhash-perl direkt aus dem Repositorie installieren. Unter Benutzung dieses Moduls muss obiges Beispiel nur leicht abgewandelt werden:
#file hashtest2.pl
use Tie::IxHash;
 
my %hash;
 
tie %hash, Tie::IxHash;
 
# ab hier kann %hash wie ein normaler Hash benutzt werden, merkt sich
# aber die Reihenfolge des Einfügens.
%hash = (
    'Feld1' => 'Wert1',
    'Auch Ein Key' => 'mit Daten',
    'Feld2' => 'Wert2',
    'Feld3' => 'Wert3',
);
 
while ( my($key,$value) = each %hash) {
    print "$key => $value\n";
}
Der Aufruf ergibt dann
$ perl hashtest.pl 
Feld1 => Wert1
Auch Ein Key => mit Daten
Feld2 => Wert2
Feld3 => Wert3
Voilá, Reihenfolge des Einfügens und der Ausgabe stimmen überein!

Trackback URL for this post:

http://www.rdoering.net/trackback/28