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


in reply to Sort hash with values

Hash lookups typically involve searching keys for values, so your logic is backwards. Rearranging the hash order and changing values to keys gives something closer to what you probably want.

sub mySort { $a =~ /(\d+)/; my $firstVal = $1; $b =~ /(\d+)/; my $secVal = $1; $firstVal <=> $secVal; } my %IP_Store = ( "UEH1_system_ip" => "11.0.0.1", "UEH11_system_ip" => "11.0.0.11", "UEH25_system_ip" => "11.0.0.3", "UEH111_system_ip" => "11.0.0.25" ); foreach my $key (sort mySort (keys (%IP_Store))) { print "$key\n"; print "System_ip = '$IP_Store{$key}' \n"; }
Update: The mySort routine looks like it's not doing it's job properly or efficiently. If you explain how you want the output sorted, I'm sure someone will have good advice.

Replies are listed 'Best First'.
Re^2: Sort hash with values
by 2teez (Vicar) on Jun 23, 2013 at 16:20 UTC

    Hi farang,
    The mySort routine looks like it's not doing it's job properly or efficiently..
    Though, I don't know how the OP wants his/her data sorted, but really there is no need for the mySort subroutine. Because, all that that subroutine is doing can be done in a sort block like so:

    use strict; use warnings; my %IP_Store = ( "11.0.0.1" => "UEH1_system_ip", "11.0.0.11" => "UEH11_system_ip", "11.0.0.3" => "UEH25_system_ip", "11.0.0.25" => "UEH111_system_ip" ); foreach my $Value ( sort { $IP_Store{$a} =~ /(\d+)/; my $firstVal = $1; $IP_Store{$b} =~ /(\d+)/; my $secVal = $1; $firstVal <=> $secVal; } keys %IP_Store ) { print "$IP_Store{$Value}\n"; print "System_ip = '$Value' \n"; }
    Which will produce the same result....

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
      Hi,

      I don't know how the OP wants his/her data sorted, but really there is no need for the mySort subroutine. Because, all that that subroutine is doing can be done in a sort block...

      Yes, you are right, but I guess that Farang wanted to offer a fix while changing as little as possible from the original code. It is often a dilemma for me (here and on other forums) when I see a clear coding error as well as a number of more or less clumsy or suboptimal things around: should we just give the bug fix to make the program work, toi solve the OP's immediate problem, or should we try to refactor the whole shebang. Sometimes, when I have time, I take the trouble of saying something like this: "your error is there, on this line of code, this is what you need to fix; but, BTW, I would think that it would also be better to (follow the following best practices | use a hash instead of an array (or an array instead of a hash) | work the algorithm the other way around | use the following (cleaner|more robust|faster) syntax | use strict and use warnings | use Perlish loops rather than C-style loops | use tr/// instead of s///g | use index instead of a regex | use map and grep instead of foreach (or foreach instead of map and grep) | whatever | etc.). But I don't always have time and I don't always do it.

        Yeah, that's basically it. I hadn't looked closely at the mySort function until after I posted, because the sort results seemed reasonable. When I did look, it seemed awkward at best, so I made note of that in an update. I was confident other monks would address it much better than I could on the spur of the moment, and sure enough 2teez and AnomalousMonk have now done just that.

        But I don't always have time and I don't always do it.

        And more often than not, advice like that is simply ignored -- being lazy is good, doesn't waste your time, doesn't annoy the OP :)