http://qs321.pair.com?node_id=1212366


in reply to Sorting hash

Hi,

since your Dump contains 2 'hostname' elements, i think you really have a ArrayRef which contains HashRefs.

you also have to take care of your sorting.

hopefully my example code helps:

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; #Hash Number 1 my %hash1 = ( 'hostname' => { '1' => { 'pass' => 1, 'cpu' => '0.07%', 'box_name' => 'hostname', 'capacity' => '0.41%' } } ); #Hash Number 2 my %hash2 = ( 'hostname' => { '1' => { 'pass' => 1, 'cpu' => '0.04%', 'box_name' => 'hostname', 'capacity' => '0.25%' } } ); #Array of Hash Refs my @array = ( \%hash1, \%hash2 ); #Array Ref my $results = \@array; #Result Elements (Hash Refs $a and $b) are dereferenced and values of +key cpu is used for sorting + foreach my $router ( sort { $a->{'hostname'}{1}{cpu} <=> $b->{'hostnam +e'}{1}{cpu} } @{$results} ) { print Dumper($router); }

Replies are listed 'Best First'.
Re^2: Sorting hash
by bartrad (Beadle) on Apr 05, 2018 at 18:39 UTC

    Hi, thanks for the reply. Sorry, I redacted the data where hostname sat. Those values are in fact unique for each key.

    'hostname1' => { '1' => { 'pass' => 1, 'cpu' => '0.1 +1%', 'box_name' => + '', 'capacity' => + '0.57%' } }, 'hostname2' => { '1' => { 'pass' => +1, 'cpu' => ' +0.09%', 'box_name' + => '', 'capacity' + => '0.43%' } },

      Hi,

      there you go.

      i must confess that i missed also 1 thing in your sort function.

      the cpu percentage will not interpreted as an numeric value, so you have to use cmp instead of <=>.

      see perlop

      #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my %results = ( 'hostname1' => { '1' => { 'pass' => 1, 'cpu' => '0.07%', 'box_name' => 'hostname', 'capacity' => '0.41%' } }, 'hostname2' => { '1' => { 'pass' => 1, 'cpu' => '0.04%', 'box_name' => 'hostname', 'capacity' => '0.25%' } } ); my $results = \%results; foreach my $router ( sort { $results->{$a}{1}{cpu} cmp $results->{$b}{ +1}{cpu} } keys %{results} ) { print Dumper($results->{$router}); }
        the cpu percentage will not interpreted as an numeric value

        Actually, due to Perl trying to numberify a string in numeric context, it turns out percents written as strings get reasonably interpreted as numbers:

        C:\WINDOWS\system32>perl -MDevel::Peek=Dump -le " $a = qq(3.14%); Dump + $a; $b = qq(2.718%); Dump $b; print $a <=> $b; Dump $a; Dump $b" SV = PV(0x1daf58) at 0x44d2660 REFCNT = 1 FLAGS = (POK,IsCOW,pPOK) PV = 0x44ebf28 "3.14%"\0 CUR = 5 LEN = 10 COW_REFCNT = 1 SV = PV(0x1dafb8) at 0x44d2300 REFCNT = 1 FLAGS = (POK,IsCOW,pPOK) PV = 0x44ebe68 "2.718%"\0 CUR = 6 LEN = 10 COW_REFCNT = 1 1 SV = PVNV(0x1d9288) at 0x44d2660 REFCNT = 1 FLAGS = (POK,IsCOW,pNOK,pPOK) IV = 0 NV = 3.14 PV = 0x44ebf28 "3.14%"\0 CUR = 5 LEN = 10 COW_REFCNT = 1 SV = PVNV(0x1d9268) at 0x44d2300 REFCNT = 1 FLAGS = (POK,IsCOW,pIOK,pNOK,pPOK) IV = 2 NV = 2.718 PV = 0x44ebe68 "2.718%"\0 CUR = 6 LEN = 10 COW_REFCNT = 1
        ... They start out as just the string (PV); but after running numeric compare, you can see that it had the right output value for $a <=> $b (1) and afterward, they also have the reasonable floating-point value (NV) of 3.14 and 2.718.