in reply to Re: Sorting hash
in thread Sorting hash

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%' } },

Replies are listed 'Best First'.
Re^3: Sorting hash
by ablanke (Monsignor) on Apr 05, 2018 at 19:01 UTC

    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.

        Hi,

        you are right, but you get an warning:

        Argument "0.04%" isn't numeric in numeric comparison (<=>)

        the sorting order, in this trivial example, is the same, but who knows what shows up in the real world.

        so a numeric compare seems to be the more obvious choice in this case.

        of course there are several ways to get rid of the warnings and using numeric comparison.