in reply to Sorting Hash Value Object's IPv4 Address

You could use inet_aton() from Socket to transform the IP into a sortable string.

use strict; use warnings; use 5.014; use Socket; my %hosts = ( host0 => { ip => q{17.198.26.3} }, host1 => { ip => q{113.34.87.9} }, host2 => { ip => q{23.6.8.136} }, host3 => { ip => q{10.45.18.207} }, host4 => { ip => q{192.168.31.8} }, host5 => { ip => q{10.17.227.3} }, host6 => { ip => q{192.168.1.6} }, host7 => { ip => q{172.16.1.1} }, host8 => { ip => q{3.77.45.22} }, host9 => { ip => q{17.216.1.1} }, ); say qq{$_ - $hosts{ $_ }->{ ip }} for map { $_->[ 0 ] } sort { $a->[ 1 ] cmp $b->[ 1 ] } map { [ $_, inet_aton($hosts{ $_ }->{ ip } ) ] } keys %hosts;

The output.

host8 - 3.77.45.22 host5 - 10.17.227.3 host3 - 10.45.18.207 host0 - 17.198.26.3 host9 - 17.216.1.1 host2 - 23.6.8.136 host1 - 113.34.87.9 host7 - 172.16.1.1 host6 - 192.168.1.6 host4 - 192.168.31.8

I hope this is helpful.

Cheers,

JohnGG

Replies are listed 'Best First'.
Re^2: Sorting Hash Value Object's IPv4 Address
by AnomalousMonk (Archbishop) on Jan 30, 2016 at 17:47 UTC

    Here's a GRT variant on the ST approach above that will, for sufficiently large datasets, be faster because it relies on the default sort comparison:

    c:\@Work\Perl\monks>perl -wMstrict -le "use Socket; ;; my %hosts = ( host0 => { ip => q{17.198.26.3} }, host1 => { ip => q{113.34.87.9} }, host2 => { ip => q{23.6.8.136} }, host3 => { ip => q{10.45.18.207} }, host4 => { ip => q{192.168.31.8} }, host5 => { ip => q{10.17.227.3} }, host6 => { ip => q{192.168.1.6} }, host7 => { ip => q{172.16.1.1} }, host8 => { ip => q{3.77.45.22} }, host9 => { ip => q{17.216.1.1} }, ); ;; my $aton = 'a4'; ;; print qq{$_ - $hosts{$_}->{ip}} for map unpack(qq{x[$aton] a*}), sort map pack(qq{$aton a*}, inet_aton($hosts{$_}->{ip}), $_), keys %hosts ; " host8 - 3.77.45.22 host5 - 10.17.227.3 host3 - 10.45.18.207 host0 - 17.198.26.3 host9 - 17.216.1.1 host2 - 23.6.8.136 host1 - 113.34.87.9 host7 - 172.16.1.1 host6 - 192.168.1.6 host4 - 192.168.31.8


    Give a man a fish:  <%-{-{-{-<

Re^2: Sorting Hash Value Object's IPv4 Address
by NetWallah (Canon) on Jan 30, 2016 at 00:47 UTC
    Good solution , and this is what I was too lazy to code, in my earlier post.

    However, shouldn't the sort use the spaceship operator (<=>) rather than cmp, since the items being compared are numeric ?

            "I can cast out either one of your demons, but not both of them." -- the XORcist

      That's what I initially assumed when I started coding this but you get a shed load of

      Argument "^CM-^V" isn't numeric in numeric comparison (<=>) at ...

      warnings when you use <=>. That's because inet_aton() is actually returning a packed string. Consider the following:-

      johngg@shiraz:~/perl/Monks > perl -MSocket -E ' > say ord for split m{}, inet_aton( q{192.168.45.92} );' 192 168 45 92 johngg@shiraz:~/perl/Monks > perl -E ' > say ord for split m{}, pack q{C4}, split m{\.}, q{192.168.45.92};' 192 168 45 92 johngg@shiraz:~/perl/Monks >

      Therefore the cmp comparison is more appropriate.

      Cheers,

      JohnGG

        Thanks for the enlightenment (++). I learned something today (always good).

                "I can cast out either one of your demons, but not both of them." -- the XORcist