my %site = ( 24j1 => { count=>1, devices=>['192.168.0.1'] }, 1924 => { count=>3, devices=>['192.168.1.1','192.168.1.3','192.168.1.9'] }, etc => { count=>2, devices=>['192.168.2.1','192.168.2.23'] }, ccp => { count=>1, devices=>['192.168.3.1'] }, ); sub my_sort { if( ("$a" ~~ @datacenters) && ("$b" ~~ @datacenters) ) { return $site{$b}->{count} <=> $site{$a}->{count}; } if( ("$a" ~~ @datacenters) && ! ( "$b" ~~ @datacenters) ) { return $a } # Warnings go away if I if( ("$b" ~~ @datacenters) && ! ( "$a" ~~ @datacenters) ) { return $b } # comment out these two lines. if( ( $a =~ $eu_regex ) && ( $b !~ $eu_regex ) ) { return $a } if( ( $b =~ $eu_regex ) && ( $a !~ $eu_regex ) ) { return $b } return $site{$b}->{count} <=> $site{$a}->{count}; } foreach my $site ( sort my_sort keys %site ) {do_stuff_with($site) }