NAME
Tie::MultiKeyInsertOrderHash
DESCRIPTION
Store multiple keys in a hash in insertion order
SYNOPSIS
tie my %hash => 'Tie::MultiKeyInsertOrderHash';
$hash{Say}="Hello World";
$hash{Do}="wave";
$hash{Say}="Good-Bye";
$hash{Do}="leave";
while (my ($key, $value) = each (%hash)) {
print "Action: $key Option: $value\n";
}
print "I said: '", join ("' and '",@{$hash{Say}}),"'\n";
print "I did: '", join ("' and '",@{$hash{Do}}),"'\n";
print "The first thing I said was $hash{Say}->[0]\n";
print "The last thing I said was $hash{Say}->[-1]\n";
Or:
tie my %hash => 'Tie::MultiKeyInsertOrderHash',A,1,B,2,A,3,B,4; #Initial values.
Notes
To complete overwrite a value use:
delete $hash{Value}
$hash{Value}="newvalue";
$hash{Value} will return an array of all values of that key; This won't work as you expect:
foreach my $key (keys %hash) {
print $key; #This will work and print the key in the right order, but the key will be printed multiple times.
print $hash{$key}; #This will print "ARRAY(......)";
print $hash{$key}->[0]; # This will print the first value multiple times.
print join(@{$hash{$key}}); #This will print all values of that key multiple times.
}
Better use: while (my ($key, $value) = each (%hash)) { print $key; print $value; #This will print every value only once and in the right order. }
OR maybe:
my %seen;
foreach my $key (grep !$seen{$_}++,keys %hash) {
print $key;
print join(@{$hash{$key}}); #This will print the keys in the right order, but the values grouped by keys.
}
BUGS
values() and scalar each() won't work do what you expect at all, because they call values(%hash) calls $hash{key} for each key, so it will return and array of arrayrefs scalar each() works, but there is no way to find out in which context each was called, so it will screw up the next $hash{key} request.
Better only use ONLY this for iterating over this hash
while (my ($key, $value) = each (%hash)) {
#do something with $key and $value
}
AUTHOR
Marc-Sebastian Lucksch
perl@maluku.de