I am struggling to find a solution in sorting a reasonably complex hash-of-hashes directly if the sort key is located a number of levels below the first keys in the hash.
I bypass this problem (inefficiently) by deriving a second simplified hash through which I can then sort by time.
Hopefully this simplified example will illustrate it more clearly:
#!/usr/bin/perl -w
use strict;
my %ERROR;
my %ERROR2;
my @classes = ('H','S','O');
my $output = <<EOD;
4865FA9B 0702 P H rmt0 TAPE OPERATION ERROR
DE9A52D1 0704 I S rmt0 DEVICE DUMP RETRIEVED
4865FA9B 0701 P H rmt2 TAPE OPERATION ERROR
F3E9B3E2 0620 I O SYSJ2 UNABLE TO ALLOCATE SPACE IN FILE SY
+STEM
DCB47997 0511 T H hdisk4 DISK OPERATION ERROR
EOD
# populate original hash
for my $line (split /\n/,$output) {
chomp $line;
my ($IDENTIFIER,$TIMESTAMP,$T,$C,$RES,$DESC) = split(/\s+/,$line,6)
+;
$ERROR{$C}{$RES}{$DESC}{time} = $TIMESTAMP;
$ERROR{$C}{$RES}{$DESC}{id} = $IDENTIFIER;
$ERROR{$C}{$RES}{$DESC}{T} = $T;
}
# elsewhere, I create a secondary hash for sorting.
my $counter = 0;
for my $CLASS (@classes) {
for my $RES (keys %{$ERROR{$CLASS}}) {
for my $DESC (keys %{$ERROR{$CLASS}{$RES}}) {
$counter++;
$ERROR2{$CLASS}{$counter}{time} = $ERROR{$CLASS}{$RES}{$DESC}
+{time};
$ERROR2{$CLASS}{$counter}{desc} = $DESC;
# ... transfer some other data from %ERROR to %ERROR2
}
}
}
# ...
# output - SORT EACH CLASS BY MOST RECENT TIME.
# sort using CLASS as primary and time as secondary key.
# note how RES and DESC have no influence on the sorting.
for my $CLASS (@classes) {
for my $nr (reverse sort {$ERROR2{$CLASS}{$a}{time} <=> $ERROR2{$CLA
+SS}{$b}{time} }
keys %{$ERROR2{$CLASS}}) {
print "CLASS $CLASS : Time : $ERROR2{$CLASS}{$nr}{time} Descript
+ion: $ERROR2{$CLASS}{$nr}{desc}\n";
}
}
I know a possibility would be to reconstruct the original hash in the %ERROR2 format - but this is not feasible due to other issues, so I'm stuck with two hashes to avoid the effect that RES and DESC keys would have when traversing %ERROR in a for loop.
Is there a method which would avoid the need for %ERROR2, and still provide output of "each class sorted by time"?
-Niel