Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re: Sorting Hash / Array

by Cristoforo (Deacon)
on May 16, 2012 at 20:46 UTC ( #970921=note: print w/ replies, xml ) Need Help??


in reply to Sorting Hash / Array

If each of the quartets was 3 digits long, (010.182.012.000/25, for example), an alphanumeric sort, cmp, would be fine. The Socket module provides a function, inet_aton(), that transforms the quartet into a sortable entity.

I added one more address to test the sort function, (with a key of 36 and value 10.182.2.0/25) Adding this record will show if the sorts are working correctly. It should sort before 10.182.12.0/25 if the sort is correct.

#!/usr/bin/env perl use strict; use warnings; use 5.014; use Socket qw/ inet_aton /; my $data = { '127' => { 'network' => '10.182.48.0/24', 'VLAN' => '3509' }, '32' => { 'network' => '10.182.12.0/25', 'VLAN' => '2121' }, '36' => { 'network' => '10.182.2.0/25', 'VLAN' => '2222' }, '90' => { 'network' => '10.183.243.128/25', 'VLAN' => '3494' } }; my @sorted_keys = map {$_->[0]} sort {$a->[1] cmp $b->[1]} map {[ $_, inet_aton( $data->{$_}{network} =~ /^([.\ +d]+)/) ]} keys %$data; for my $key (@sorted_keys) { printf "%4d%20s%6s\n", $key, $data->{$key}{network}, $data->{$key} +{VLAN}; }

The output is,

C:\Old_Data\perlp>perl 970882.pl 36 10.182.2.0/25 2222 32 10.182.12.0/25 2121 127 10.182.48.0/24 3509 90 10.183.243.128/25 3494 C:\Old_Data\perlp>

If I add the additional line to kcott's code, it gives the following output:

C:\Old_Data\perlp>perl t.pl Key Network VLAN 32 10.182.12.0/25 2121 36 10.182.2.0/25 2222 127 10.182.48.0/24 3509 90 10.183.243.128/25 3494

Hope this helps,

Chris

Update: I see that johngg beat me to the answer and his explanation of why the lexical sort won't sort correctly and why Socket should be used instaed.


Comment on Re: Sorting Hash / Array
Select or Download Code
Re^2: Sorting Hash / Array
by nickt9999 (Acolyte) on May 16, 2012 at 22:27 UTC

    This is why I should have asked the experts at the beginning.

    I really appreciate all your help

    Thanks again

    Cheers

    Nick

Re^2: Sorting Hash / Array
by nickt9999 (Acolyte) on May 17, 2012 at 16:09 UTC

    Hi Chris

    I Have a bit of an issue in that it doesn't seem to sort subnets correctly.

    10.182.8.0/26 10.182.8.0/21 10.182.8.64/26 10.182.8.128/26 10.182.8.192/26
    10.182.32.0/24 10.182.32.0/19 10.182.33.0/24

    I would expect 10.182.8.0/21 to be before 10.182.8.0/26

    Could you help?

    Thanks

    Nick

      Split the network and netmask into separate terms and sort on netmask within network.

      knoppix@Microknoppix:~$ perl -MSocket -Mstrict -wE ' my @networks = qw{ 10.182.8.0/26 10.182.8.0/21 10.182.8.64/26 10.182.8.128/26 10.182.8.192/26 }; say for map { $_->[ 0 ] } sort { $a->[ 1 ] cmp $b->[ 1 ] || $a->[ 2 ] <=> $b->[ 2 ] } map { my( $network, $netmask ) = split m{/}; [ $_, inet_aton( $network ), $netmask ]; } @networks;' 10.182.8.0/21 10.182.8.0/26 10.182.8.64/26 10.182.8.128/26 10.182.8.192/26 knoppix@Microknoppix:~$

      I hope this is helpful.

      Cheers,

      JohnGG

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://970921]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (8)
As of 2014-07-12 13:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (240 votes), past polls