Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
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 examining the Monastery: (3)
As of 2015-07-03 22:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (57 votes), past polls