my $VAR1 = { 'A' => [0,1,2], # centroid is 1, with other elem 0 and 2 (1 +/- 1) 'B' => [1,2,3], 'C' => [2,3,4], 'D' => [3,4,5], 'E' => [4,5,6], 'F' => [5,6], # centroid is 6 but only with one elem 5 (i.e. 6-1) 'G' => [8], # next centroid is 8 but no members 'I' => [10], # same for centroid 10 }; # As the @nlist array grow larger the final hash will also grow larger. #### use strict; use Data::Dumper; use Carp; # Size of this array could be much greater than this my @nlist = ( 0, 1, 2, 3, 4, 5, 6, 8, 10 ); # And the first element can be greater than 0 # This is a pre-generated key candidate. # It may not be used up all of them # In practice I will create a large key list, # that should be greater than potential hash to be created my @key_list = ( 'A' .. 'Z' ); my $tolerance = 1; my $hoa; foreach my $nlist (@nlist) { my @tmpar = ($nlist[0]); my $first_elem = $nlist[0]; my $klist; if ( check_member( \@tmpar, $first_elem, $nlist, $tolerance ) == 1 ) { push @tmpar, $nlist; $klist = shift @key_list; push @{ $hoa->{$klist} }, @tmpar; } } print Dumper $hoa; # -- Subroutine ------ sub check_member { # To check if a value can be # a member of an array my ( $alist, $fel, $snum,$tol ) = @_; my $centroid = $alist->[0]; if ( $centroid - $tol == $snum or $centroid + $tol == $snum or $centroid == $snum and $centroid != $fel ) { return 1; } return 0; }