Re: Sorting Multilevel Hashes
by Not_a_Number (Prior) on Apr 24, 2014 at 23:00 UTC
|
I don't have an answer for you, but, then, you don't have a question, do you? :-)
I do, however, have several comments:
| [reply] [d/l] [select] |
|
|
pin Name related_pin time_type rise_fall delay
DQ5_RX_CLK M2CLKP c_rise rise_transition 0.014446
DQ2_RX_CLK M2CLKP c_rise rise_transition 0.014464
DQ0_RX_CLK M2CLKP c_rise rise_transition 0.014452
DQ3_RX_CLK M2CLKP c_rise rise_transition 0.014452
DQ7_RX_CLK M2CLKP c_rise rise_transition 0.014430
DQ4_RX_CLK M2CLKP c_rise rise_transition 0.014446
DQ8_RX_CLK INT_CLK c_fall fall_transition 0.199360
DQ6_RX_CLK INT_CLK c_fall fall_transition 0.199322
DQ1_RX_CLK INT_CLK c_fall fall_transition 0.199500
DQ5_RX_CLK INT_CLK c_fall fall_transition 0.199248
DQ2_RX_CLK INT_CLK c_fall fall_transition 0.199368
to create the hash I read in a file
$timing1{$related_pin}{$timing_type}{$rise_fall}{$pinname} = $delay;
Here is my code
foreach my $rName ( keys %timing1 ) {
foreach my $tType ( sort keys %{$timing1{$rName}}) {
+
foreach my $rF ( sort keys %{$timing1{$rName}{$tType}}){
+
foreach my $pinName ( keys %{$timing1{$rName}{$tType}{$rF}})
+{
print OUTFILE2 " $pinName\t $rName\t $tType\t $rF\t $timin
+g1{$rName}{$tType}{$rF}{$pinName} \n";
}
}
}
}
| [reply] [d/l] [select] |
|
|
use strict;
use warnings;
my %timing1;
chomp ($_=<DATA>); # Hdr
my @hdr = split /\s+/;
while (<DATA>){
chomp ;
s/^\s+//;
my @r=split /\s+/;
$timing1{$r[1]}{$r[2]}{$r[3]}{$r[0]}=$r[4];
}
foreach my $rName ( keys %timing1 ) {
foreach my $tType ( sort keys %{$timing1{$rName}}) {
foreach my $rF ( sort keys %{$timing1{$rName}{$tType}}){
+
my @by_val = map {[$timing1{$rName}{$tType}{$rF}{$_},$_]}
keys %{$timing1{$rName}{$tType}{$rF}};
@by_val = sort { $a->[0] <=> $b->[0]} @by_val;
foreach my $aref ( @by_val) {
my ($val, $pinName) = @$aref;
print " $pinName\t $rName\t $tType\t $rF\t $val \n";
}
}
}
}
__DATA__
pin Name related_pin time_type rise_fall delay
DQ5_RX_CLK M2CLKP c_rise rise_transition 0.014446
DQ2_RX_CLK M2CLKP c_rise rise_transition 0.014464
DQ0_RX_CLK M2CLKP c_rise rise_transition 0.014452
DQ3_RX_CLK M2CLKP c_rise rise_transition 0.014452
DQ7_RX_CLK M2CLKP c_rise rise_transition 0.014430
DQ4_RX_CLK M2CLKP c_rise rise_transition 0.014446
DQ8_RX_CLK INT_CLK c_fall fall_transition 0.199360
DQ6_RX_CLK INT_CLK c_fall fall_transition 0.199322
DQ1_RX_CLK INT_CLK c_fall fall_transition 0.199500
DQ5_RX_CLK INT_CLK c_fall fall_transition 0.199248
DQ2_RX_CLK INT_CLK c_fall fall_transition 0.199368
OUTPUT:
DQ7_RX_CLK M2CLKP c_rise rise_transition 0.014430
DQ4_RX_CLK M2CLKP c_rise rise_transition 0.014446
DQ5_RX_CLK M2CLKP c_rise rise_transition 0.014446
DQ3_RX_CLK M2CLKP c_rise rise_transition 0.014452
DQ0_RX_CLK M2CLKP c_rise rise_transition 0.014452
DQ2_RX_CLK M2CLKP c_rise rise_transition 0.014464
DQ5_RX_CLK INT_CLK c_fall fall_transition 0.199
+248
DQ6_RX_CLK INT_CLK c_fall fall_transition 0.199
+322
DQ8_RX_CLK INT_CLK c_fall fall_transition 0.199
+360
DQ2_RX_CLK INT_CLK c_fall fall_transition 0.199
+368
DQ1_RX_CLK INT_CLK c_fall fall_transition 0.199
+500
What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?
-Larry Wall, 1992
| [reply] [d/l] [select] |
|
|
|
|
|
|
|
|
| [reply] |
Re: Sorting Multilevel Hashes
by hdb (Monsignor) on Apr 25, 2014 at 06:29 UTC
|
If you only want to print the sorted rows into another file, then IMHO it is easier to read the file into an array of arrays and sort them then.
use strict;
use warnings;
my $header = <DATA>;
my @rows =
map { join "\t", @$_ }
sort { $a->[1] cmp $b->[1] ||
$a->[2] cmp $b->[2] ||
$a->[3] cmp $b->[3] ||
$a->[4] <=> $b->[4]
}
map {[ split /\s+/ ]} <DATA>;
print $header;
print "$_\n" for @rows;
__DATA__
pin Name related_pin time_type rise_fall delay
DQ5_RX_CLK M2CLKP c_rise rise_transition 0.014446
DQ2_RX_CLK M2CLKP c_rise rise_transition 0.014464
DQ0_RX_CLK M2CLKP c_rise rise_transition 0.014452
DQ3_RX_CLK M2CLKP c_rise rise_transition 0.014452
DQ7_RX_CLK M2CLKP c_rise rise_transition 0.014430
DQ4_RX_CLK M2CLKP c_rise rise_transition 0.014446
DQ8_RX_CLK INT_CLK c_fall fall_transition 0.199360
DQ6_RX_CLK INT_CLK c_fall fall_transition 0.199322
DQ1_RX_CLK INT_CLK c_fall fall_transition 0.199500
DQ5_RX_CLK INT_CLK c_fall fall_transition 0.199248
DQ2_RX_CLK INT_CLK c_fall fall_transition 0.199368
| [reply] [d/l] |
Re: Sorting Multilevel Hashes
by hippo (Archbishop) on Apr 24, 2014 at 22:45 UTC
|
To my eyes that code is bordering on unmaintainable. If you are attempting to sort by key at each level in turn (which is what I think you are doing - correct me if that isn't the case) then think about recursion. Applying the relevant FAQ (which also discusses sorting by value) just once in a recursive subroutine should do the trick without resorting to $foo{$bar}{$baz}{$quux}{$frob} constructs.
| [reply] [d/l] |
|
|
| [reply] |
|
|
#!/usr/bin/perl -Tw
#
# Multi-level hash sort
use strict;
use warnings;
my %timing1 = initmyhash();
printsortedhash (\%timing1, '');
exit;
sub initmyhash {
# Obviously, put whatever sets up your hash here.
return ( dog => 'rover', cat => { name => 'sandy', age => 10 } );
}
sub printsortedhash {
my ($this, $report) = @_;
for my $key (sort keys %$this) {
if (ref $this->{$key} eq 'HASH') {
printsortedhash ($this->{$key}, $report . "\t $key")
} else {
print $report . "\t $key\t $this->{$key}\n";
}
}
}
The FAQ linked above shows how to sort by value instead/also. Take your pick. | [reply] [d/l] |
Re: Sorting Multilevel Hashes
by Anonymous Monk on Apr 24, 2014 at 23:26 UTC
|
| [reply] |