http://www.perlmonks.org?node_id=1212370


in reply to Re^2: Sorting hash
in thread Sorting hash

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}); }

Replies are listed 'Best First'.
Re^4: Sorting hash
by pryrt (Prior) on Apr 05, 2018 at 19:30 UTC
    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.

        You're right. That'll remind me to turn on warnings even for oneliners...