package Point; use strict; use warnings; use Data::Dumper; my @data = (...) #see data_sets below my @new_data; while ( @data ) { my $item = shift @data; my $match; foreach (0 .. $#data ) { if ( $data[$_][0]{X} == @{$item}[-1]->{X} and $data[$_][0]{Y} == @{$item}[-1]->{Y} ) { $match = ['front', $_ ]; last; } if ( $data[$_][-1]{X} == @{$item}[0]->{X} and $data[$_][-1]{Y} == @{$item}[0]->{Y} ) { $match = ['end' , $_ ]; last; } } if ( defined $match ) { if ( @{$match}[0] eq 'front' ) { splice @{$data[@{$match}[1]]},0,1,@{$item}; } else { splice @{$data[@{$match}[1]]},-1,1,@{$item}; } } else { push @new_data,$item; } } print Dumper \@new_data;