use strict; use warnings; use Data::Dump 'dump'; my @numbers = ( 1, 2, 2, 4, 8, 42, 7, 2, 6, 7, 9, 42 ); my @duplicate_locations = find_duplicates( @numbers ); dump @duplicate_locations; sub find_duplicates { my @list = @_; my $idx; my %buckets; foreach my $item ( @list ) { push @{$buckets{$item}}, $idx++; } my @rv; foreach my $key ( keys %buckets ) { push @rv, { $list[$buckets{$key}->[0]] => $buckets{$key} } if @{$buckets{$key}} > 1; } return @rv; } #### ({ 42 => [5, 11] }, { 7 => [6, 9] }, { 2 => [1, 2, 7] }) #### use strict; use warnings; use Data::Dump 'dump'; my @numbers = ( 1, 2, 2, 4, 8, 42, 7, 2, 6, 7, 9, 42 ); dump { find_duplicates( @numbers ) }; sub find_duplicates { my @list = @_; my $idx; my %buckets; foreach my $item ( @list ) { push @{$buckets{$item}}, $idx++; } delete @buckets{ grep { @{$buckets{$_}} < 2 } keys %buckets }; return %buckets; } #### { 2 => [1, 2, 7], 7 => [6, 9], 42 => [5, 11] }